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

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

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.


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).*$"));

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

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

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


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

1

Versuche dies:

if (Arrays.asList(item1, item2, item3).stream().anyMatch(string::contains))

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() ){ 

}

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

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.

-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 .


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.