Jak sprawdzić, czy ciąg znaków zaczyna się od jednego z kilku prefiksów?

101

Mam następujące oświadczenie if:

String newStr4 = strr.split("2012")[0];
if (newStr4.startsWith("Mon")) {
    str4.add(newStr4);
}

Chcę, aby zawierał startsWith Mon Tues Weds Thurs Fridayitd. Czy istnieje prosty sposób na to, gdy używa się ciągów? Próbowałem, ||ale to nie zadziałało.

FredBones
źródło
4
Masz na myśli, że próbowałeś "Mon||Tues"itp.? Czy użyłeś newStr4.startsWith("Mon")||newStr4.startsWith("Tues") ...? Tak czy inaczej, określ „to nie zadziałało”.
Thomas
Czy przypadkiem próbujesz przeanalizować datę? Jeśli tak, użyj SimpleDateFormat ...
Adam

Odpowiedzi:

176

Masz na myśli to:

if (newStr4.startsWith("Mon") || newStr4.startsWith("Tues") || ...)

Lub możesz użyć wyrażenia regularnego:

if (newStr4.matches("(Mon|Tues|Wed|Thurs|Fri).*"))
hmjd
źródło
2
Czy jest jakaś różnica w wydajności dwóch sugerowanych metod?
TheCrazyProgrammer
6
@TheCrazyProgrammer Oczywiście, że jest; dopasowywanie za pomocą wyrażeń regularnych jest znacznie droższe niż wywołania metod z nieprzetworzonymi łańcuchami. Nie mogę podać dokładnych liczb, ale taki jest ogólny konsensus.
klaar
52

Oprócz przedstawionych już rozwiązań możesz skorzystać z biblioteki Apache Commons Lang:

if(StringUtils.startsWithAny(newStr4, new String[] {"Mon","Tues",...})) {
  //whatever
}

Aktualizacja: wprowadzenie w pewnym momencie varargs upraszcza teraz połączenie:

StringUtils.startsWithAny(newStr4, "Mon", "Tues",...)
Tomasz
źródło
31

Nikt do Streamtej pory nie wymieniony , więc oto:

if (Stream.of("Mon", "Tues", "Wed", "Thurs", "Fri").anyMatch(s -> newStr4.startsWith(s)))
dejvuth
źródło
6
świetne (i up-to-date) odpowiedzi ... btw s -> newStr4.startsWith(s)może być zastąpiona newStr7::startsWithbyć jaśniejsze
Jordi Castilla
Jak mogę zignorować przypadek tutaj?
happybuddha
Możesz użyć funkcji String toLowerCase ().
Ilia Kopysov
7

Prostym rozwiązaniem jest:

if (newStr4.startsWith("Mon") || newStr4.startsWith("Tue") || newStr4.startsWith("Wed"))
// ... you get the idea ...

Bardziej wyszukanym rozwiązaniem byłoby:

List<String> days = Arrays.asList("SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT");
String day = newStr4.substring(0, 3).toUpperCase();
if (days.contains(day)) {
    // ...
}
Óscar López
źródło
3
Lub Arrays.binarySearch (), jeśli lista wyszukiwania jest posortowana: D
Brendan Long
2
@BrendanDuża przesada jak na tak krótką listę, ale ok :)
Óscar López
3

Oczywiście pamiętaj, że Twój program będzie przydatny tylko w krajach anglojęzycznych, jeśli wykryjesz daty w ten sposób. Warto rozważyć:

Set<String> dayNames = Calendar.getInstance()
 .getDisplayNames(Calendar.DAY_OF_WEEK,
      Calendar.SHORT,
      Locale.getDefault())
 .keySet();

Stamtąd możesz użyć .startsWith lub .matches lub jakiejkolwiek innej metody, o której inni wspomnieli powyżej. W ten sposób otrzymujesz domyślne ustawienia regionalne dla jvm. Zawsze możesz przekazać ustawienia regionalne (i może domyślnie ustawić ustawienia regionalne systemu, jeśli są puste), aby były bardziej niezawodne.

Matt
źródło
1
if(newStr4.startsWith("Mon") || newStr4.startsWith("Tues") || newStr4.startsWith("Weds") .. etc)

Musisz uwzględnić całość str.startsWith(otherStr)dla każdego elementu, ponieważ ||działa tylko z wyrażeniami logicznymi (prawda lub fałsz).

Istnieją inne opcje, jeśli masz wiele rzeczy do sprawdzenia, na przykład wyrażenia regularne , ale zwykle są one wolniejsze, a bardziej skomplikowane wyrażenia regularne są na ogół trudniejsze do odczytania.

Przykładowe wyrażenie regularne służące do wykrywania skrótów nazw dni to:

if(Pattern.matches("Mon|Tues|Wed|Thurs|Fri", stringToCheck)) {
Brendan Long
źródło
0

Kiedy mówisz, że próbowałeś użyć OR, jak dokładnie próbowałeś go użyć? W twoim przypadku będziesz musiał zrobić coś takiego:

String newStr4 = strr.split("2012")[0];
if(newStr4.startsWith("Mon") || newStr4.startsWith("Tues")...)
str4.add(newStr4);
npinti
źródło