Jak przetestować ciąg, aby sprawdzić, czy zawiera którykolwiek z ciągów z tablicy?
Zamiast używać
if (string.contains(item1) || string.contains(item2) || string.contains(item3))
Jak przetestować ciąg, aby sprawdzić, czy zawiera którykolwiek z ciągów z tablicy?
Zamiast używać
if (string.contains(item1) || string.contains(item2) || string.contains(item3))
Odpowiedzi:
EDYCJA: Oto aktualizacja wykorzystująca API strumieniowania Java 8. O wiele czystsze. Nadal można go również łączyć z wyrażeniami regularnymi.
public static boolean stringContainsItemFromList(String inputStr, String[] items) {
return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
}
Ponadto, jeśli zmienimy typ danych wejściowych na List zamiast tablicy, której możemy użyć items.parallelStream().anyMatch(inputStr::contains)
.
Możesz również użyć, .filter(inputStr::contains).findAny()
jeśli chcesz zwrócić pasujący ciąg.
Oryginalna nieco przestarzała odpowiedź:
Oto (BARDZO PODSTAWOWA) metoda statyczna. Zauważ, że w łańcuchach porównania rozróżniana jest wielkość liter. Prymitywny sposób, aby to wielkość liter ma znaczenie byłoby zadzwonić toLowerCase()
lubtoUpperCase()
na obu ciągów wejściowych i testowych.
Jeśli potrzebujesz zrobić coś bardziej skomplikowanego niż to, polecam przyjrzenie się klasom Pattern i Matcher i nauczenie się wykonywania wyrażeń regularnych. Gdy je zrozumiesz, możesz użyć tych klas lub String.matches()
metody pomocniczej.
public static boolean stringContainsItemFromList(String inputStr, String[] items)
{
for(int i =0; i < items.length; i++)
{
if(inputStr.contains(items[i]))
{
return true;
}
}
return false;
}
import org.apache.commons.lang.StringUtils;
Posługiwać się:
StringUtils.indexOfAny(inputString, new String[]{item1, item2, item3})
Zwróci indeks znalezionego ciągu lub -1, jeśli żaden nie zostanie znaleziony.
Możesz użyć metody String # match w następujący sposób:
System.out.printf("Matches - [%s]%n", string.matches("^.*?(item1|item2|item3).*$"));
Najłatwiejszym sposobem byłoby prawdopodobnie przekonwertowanie tablicy na java.util.ArrayList. Gdy znajdzie się na liście arraylistów, możesz łatwo wykorzystać metodę zawierającą.
public static boolean bagOfWords(String str)
{
String[] words = {"word1", "word2", "word3", "word4", "word5"};
return (Arrays.asList(words).contains(str));
}
string
zawiera jakieś String
s w tablicy, a nie czy zawiera jakieś String
s w tablicy string
.
.equals()
w swoim poście, co jest bardzo mylące. Myślę, że muszą zmienić swoje pytanie
Jeśli używasz Java 8 lub nowszej, możesz polegać na Stream API, aby zrobić coś takiego:
public static boolean containsItemFromArray(String inputString, String[] items) {
// Convert the array of String items as a Stream
// For each element of the Stream call inputString.contains(element)
// If you have any match returns true, false otherwise
return Arrays.stream(items).anyMatch(inputString::contains);
}
Zakładając, że masz dużą tablicę dużych String
do przetestowania, możesz również uruchomić wyszukiwanie równolegle, wywołując parallel()
, kod wyglądałby wtedy:
return Arrays.stream(items).parallel().anyMatch(inputString::contains);
Oto jedno rozwiązanie:
public static boolean containsAny(String str, String[] words)
{
boolean bResult=false; // will be set, if any of the words are found
//String[] words = {"word1", "word2", "word3", "word4", "word5"};
List<String> list = Arrays.asList(words);
for (String word: list ) {
boolean bFound = str.contains(word);
if (bFound) {bResult=bFound; break;}
}
return bResult;
}
Począwszy od wersji 3.4 Apache Common Lang 3 zaimplementowano metodę containsAny .
Bardziej groovyesque byłoby użycie wstrzyknięcia w połączeniu z metaClass :
Bardzo chciałbym powiedzieć:
String myInput="This string is FORBIDDEN"
myInput.containsAny(["FORBIDDEN","NOT_ALLOWED"]) //=>true
A metoda byłaby taka:
myInput.metaClass.containsAny={List<String> notAllowedTerms->
notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}
Jeśli chcesz, aby zawierała ona wszystkie przyszłe zmienne typu String, dodaj metodę do klasy zamiast do obiektu:
String.metaClass.containsAny={notAllowedTerms->
notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}
Spróbuj tego:
if (Arrays.asList(item1, item2, item3).stream().anyMatch(string::contains))
Jeśli szukasz całych słów, możesz to zrobić bez rozróżniania wielkości liter .
private boolean containsKeyword(String line, String[] keywords)
{
String[] inputWords = line.split(" ");
for (String inputWord : inputWords)
{
for (String keyword : keywords)
{
if (inputWord.equalsIgnoreCase(keyword))
{
return true;
}
}
}
return false;
}
Możemy też zrobić tak:
if (string.matches("^.*?((?i)item1|item2|item3).*$"))
(?i): used for case insensitive
.*? & .*$: used for checking whether it is present anywhere in between the string.
Poniższe powinno zadziałać, zakładając, że ciągi znaków to tablica, w której szukasz:
Arrays.binarySearch(Strings,"mykeytosearch",mysearchComparator);
gdzie mykeytosearch to ciąg, który chcesz sprawdzić pod kątem istnienia w tablicy. mysearchComparator - to komparator, który byłby używany do porównywania ciągów.
Więcej informacji zawiera Arrays.binarySearch .
if (Arrays.asList(array).contains(string))