Testen Sie, ob eine Zeichenfolge eine der Zeichenfolgen aus einem Array enthält

153

Wie teste ich eine Zeichenfolge, um festzustellen, ob sie Zeichenfolgen aus einem Array enthält?

Anstatt zu verwenden

if (string.contains(item1) || string.contains(item2) || string.contains(item3))
arowell
quelle
4
Sind Sie fragen , ob ein String ist gleich einer des Strings im Array oder enthält jede der Saiten von im Array?
Natix
1
Sie möchten überprüfen, ob eine Zeichenfolge aus dem Array eine Teilzeichenfolge Ihrer Eingabezeichenfolge ist? Oder Sie wollen überprüfen , ob Ihre Eingabe - String entspricht einer der Zeichenfolge im Array? Können Sie genauer sein?
Savino Sguera
1
enthält, so dass es eine Zeile nimmt und sieht, ob es eines der Wörter aus einer Liste enthält (als Array von Zeichenfolgen gespeichert)
arowell

Antworten:

186

BEARBEITEN: Hier ist ein Update mit der Java 8 Streaming API. So viel sauberer. Kann auch noch mit regulären Ausdrücken kombiniert werden.

public static boolean stringContainsItemFromList(String inputStr, String[] items) {
    return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
}

Wenn wir den Eingabetyp in eine Liste anstelle eines Arrays ändern, können wir ihn auch verwenden items.parallelStream().anyMatch(inputStr::contains) .

Sie können auch verwenden, .filter(inputStr::contains).findAny()wenn Sie die übereinstimmende Zeichenfolge zurückgeben möchten.


Ursprüngliche leicht veraltete Antwort:

Hier ist eine (SEHR GRUNDLEGENDE) statische Methode. Beachten Sie, dass bei den Vergleichszeichenfolgen zwischen Groß- und Kleinschreibung unterschieden wird. Eine primitive Möglichkeit, die Groß- und Kleinschreibung nicht zu berücksichtigen, besteht darin, die Eingabe- und die Testzeichenfolge aufzurufen toLowerCase()oder toUpperCase()zu aktivieren.

Wenn Sie etwas komplizierteres tun müssen, würde ich empfehlen, sich das Muster anzusehen und Matcher Klassen und lernen , wie man einige reguläre Ausdrücke zu tun. Sobald Sie diese verstanden haben, können Sie diese Klassen oder die String.matches()Hilfsmethode verwenden.

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;
}
gnomed
quelle
1
Wie man es mit regulären Ausdrücken benutzt @gnomed
Praneeth
Wie können wir die erste Implementierung zwischen Groß- und Kleinschreibung unterscheiden?
thanos.a
Die Implementierungen unterscheiden bereits zwischen Groß- und Kleinschreibung. In den unteren Absätzen der Antwort finden Sie auch Anweisungen, wie Sie die Groß- und Kleinschreibung nicht berücksichtigen können.
Gnomed
52
import org.apache.commons.lang.StringUtils;

String Utils

Verwenden:

StringUtils.indexOfAny(inputString, new String[]{item1, item2, item3})

Es wird der Index der gefundenen Zeichenfolge oder -1 zurückgegeben, wenn keine gefunden wird.

Renanleandrof
quelle
7
JFI: Ich hatte gehofft, dass diese Implementierung nur einmal über den inputString iteriert, aber ich habe mir den Code in StringUtils angesehen, und leider werden nur N Aufrufe des StandardindexOf ausgeführt.
Alfonx
Vielleicht ist auf commons3 die Implementierung besser!
Renanleandrof
1
Nein, iteriert immer noch nur über die Zeichenfolgen in org.apache.commons.lang3.StringUtils: for (int i = 0; i <searchStrs.length; i ++) {CharSequenceUtils.indexOf (str, search, 0); ....
Alfonx
Dies gibt nicht den Index der gefundenen Zeichenfolge (aus dem Array) zurück, sondern nur den Index der Position, an der die Zeichenfolge gefunden wurde.
Pluto
33

Sie können die String # match- Methode wie folgt verwenden:

System.out.printf("Matches - [%s]%n", string.matches("^.*?(item1|item2|item3).*$"));
Anubhava
quelle
16

Der einfachste Weg wäre wahrscheinlich, das Array in eine java.util.ArrayList zu konvertieren. Sobald es sich in einer Arrayliste befindet, können Sie die Contains-Methode problemlos nutzen.

public static boolean bagOfWords(String str)
{
    String[] words = {"word1", "word2", "word3", "word4", "word5"};  
    return (Arrays.asList(words).contains(str));
}
Roy Kachouh
quelle
69
Das ist falsch. OP wird gefragt , ob stringirgendwelche enthält Strings in dem Array, nicht , ob irgendwelche Strings in dem Array enthalten string.
Beau Grantham
3
@BeauGrantham Ich habe das auch gedacht, aber das OP verwendet .equals()in ihrem Beitrag, was sehr verwirrend ist. Ich denke, sie müssen ihre Frage bearbeiten
gnomed
@BeauGrantham Mann Ich konnte nicht schwören, dass ich das Problem verstanden habe. Vielleicht muss die Frage etwas genauer geklärt werden?
Roy Kachouh
1
Nein, diese Art der umgekehrten Richtung funktioniert nicht. Sie sollten überprüfen, ob der String EINEN der angegebenen Werte enthält und NICHT, ob die angegebenen Werte den String enthalten.
Vladimir Stazhilov
2
Frage ist das Gegenteil
Stéphane GRILLON
16

Wenn Sie Java 8 oder höher verwenden, können Sie sich auf die Stream-API verlassen , um Folgendes zu tun:

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);
}

Angenommen, Sie haben eine große Auswahl an Big- StringTests, können Sie die Suche auch parallel durch Aufrufen starten. parallel()Der Code lautet dann:

return Arrays.stream(items).parallel().anyMatch(inputString::contains); 
Nicolas Filotto
quelle
Eine seltsame Sache, die mir aufgefallen ist: Ich habe zwei Elemente in der String-Liste. Ich habe herausgefunden, dass bei Verwendung von 'parallel' nicht die richtigen Ergebnisse zurückgegeben werden. (auch wenn es den Wert enthält).
CharlesC
@ Charles.C das ist komisch ich kann nicht auf meiner Seite reproduzieren.
Nicolas Filotto
Ich bin mir ziemlich sicher, dass die Parallelisierung des Streams hier nicht optimal wäre, wenn die Eingabezeichenfolge nicht lang wäre (~ 500 Zeichen). Wenn das Array groß wäre, wäre es wahrscheinlich besser, das Array zu partitionieren und jedes davon parallel auszuführen.
Lebensbedingter
2

Hier ist eine Lösung:

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;
}
serup
quelle
2

Seit der Version 3.4 Apache Commons Lang 3 , um die Umsetzung containsAny Methode.

Arthur Vaïsse
quelle
Das prüft auf Char Array
Saikat
1

Ein groovyesque Ansatz wäre die Verwendung inject in Kombination mit Metaklasse :

Ich würde gerne sagen:

String myInput="This string is FORBIDDEN"
myInput.containsAny(["FORBIDDEN","NOT_ALLOWED"]) //=>true

Und die Methode wäre:

myInput.metaClass.containsAny={List<String> notAllowedTerms->
   notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}

Wenn Sie containsAny anwesend zu sein für jedes zukünftige String - Variable dann das Verfahren auf die anstelle der Objektklasse hinzu:

String.metaClass.containsAny={notAllowedTerms->
   notAllowedTerms?.inject(false,{found,term->found || delegate.contains(term)})
}
Ivan Arrizabalaga
quelle
1

Versuche dies:

if (Arrays.asList(item1, item2, item3).stream().anyMatch(string::contains))
Óscar López
quelle
15
Die Frage ist das Gegenteil: Enthält die Zielzeichenfolge eine der Zeichenfolgen der Liste?
Basil Bourque
1
Frage ist das Gegenteil
Stéphane GRILLON
0

Wenn Sie nach einer Übereinstimmung suchen, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird, verwenden Sie das Muster

Pattern pattern = Pattern.compile("\\bitem1 |item2\\b",java.util.regex.Pattern.CASE_INSENSITIVE);

    Matcher matcher = pattern.matcher(input);
    if(matcher.find() ){ 

}
vsingh
quelle
0

Wenn Sie nach ganzen Wörtern suchen , können Sie dies tun, ohne die Groß- und Kleinschreibung zu beachten .

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;
}
thanos.a
quelle
0

Das können wir auch so machen:

if (string.matches("^.*?((?i)item1|item2|item3).*$"))
(?i): used for case insensitive
.*? & .*$: used for checking whether it is present anywhere in between the string.
Chandan Kolambe
quelle
-3

Das Folgende sollte für Sie funktionieren, vorausgesetzt, Strings ist das Array, in dem Sie suchen:

Arrays.binarySearch(Strings,"mykeytosearch",mysearchComparator);

Dabei ist mykeytosearch die Zeichenfolge, die Sie auf Existenz innerhalb des Arrays testen möchten. mysearchComparator - ist ein Komparator, der zum Vergleichen von Zeichenfolgen verwendet wird.

Weitere Informationen finden Sie unter Arrays.binarySearch .

Prahalad Deshpande
quelle
2
Es ist zu beachten, dass binarySearch nur mit Arrays funktioniert, die entweder natürlich oder nach dem angegebenen Komparator sortiert sind (falls vorhanden).
Natix
-4
if (Arrays.asList(array).contains(string))
Garrett Hall
quelle
10
Die Frage ist das Gegenteil: Enthält die Zielzeichenfolge eine der Zeichenfolgen der Liste?
Basil Bourque
2
Frage ist das Gegenteil
Stéphane GRILLON