Überprüfen Sie, ob eine Zeichenfolge in Java mehrere Schlüsselwörter enthält

1. Einleitung

In diesem kurzen Tutorial erfahren Sie, wie Sie mehrere Wörter in einer Zeichenfolge erkennen .

2. Unser Beispiel

Nehmen wir an, wir haben die Zeichenfolge:

String inputString = "hello there, Baeldung";

Unsere Aufgabe ist es zu finden , ob der input enthält die „Hallo“ und „Baeldung“ Worte.

Fügen wir also unsere Schlüsselwörter in ein Array ein:

String[] words = {"hello", "Baeldung"};

Darüber hinaus ist die Reihenfolge der Wörter nicht wichtig, und bei den Übereinstimmungen sollte zwischen Groß- und Kleinschreibung unterschieden werden.

3. Verwenden von String.contains ()

Als Start, zeigen wir , wie die verwenden String.contains () Methode , um unser Ziel zu erreichen .

Lassen Sie uns das Schlüsselwort-Array durchlaufen und das Auftreten jedes Elements im inputString überprüfen:

public static boolean containsWords(String inputString, String[] items) { boolean found = true; for (String item : items) { if (!inputString.contains(item)) { found = false; break; } } return found; }

Die Methode includes () gibt true zurück, wenn der inputString das angegebene Element enthält . Wenn wir keines der Schlüsselwörter in unserer Zeichenfolge haben, können wir aufhören, vorwärts zu gehen, und sofort ein falsches zurückgeben .

Trotz der Tatsache, dass wir mehr Code schreiben müssen, ist diese Lösung für einfache Anwendungsfälle schnell.

4. Verwenden von String.indexOf ()

Ähnlich wie bei der Lösung, die die String.contains () -Methode verwendet, können wir die Indizes der Schlüsselwörter mithilfe der String.indexOf () -Methode überprüfen . Dafür benötigen wir eine Methode, die den inputString und die Liste der Schlüsselwörter akzeptiert :

public static boolean containsWordsIndexOf(String inputString, String[] words) { boolean found = true; for (String word : words) { if (inputString.indexOf(word) == -1) { found = false; break; } } return found; }

Die Methode indexOf () gibt den Index des Wortes innerhalb des inputString zurück . Wenn wir das Wort nicht im Text haben, ist der Index -1.

5. Verwenden regulärer Ausdrücke

Verwenden wir jetzt einen regulären Ausdruck, der unseren Wörtern entspricht. Dafür verwenden wir die Pattern- Klasse.

Definieren wir zunächst den Zeichenfolgenausdruck. Da wir zwei Schlüsselwörter abgleichen müssen, erstellen wir unsere Regex-Regel mit zwei Lookaheads:

Pattern pattern = Pattern.compile("(?=.*hello)(?=.*Baeldung)");

Und für den allgemeinen Fall:

StringBuilder regexp = new StringBuilder(); for (String word : words) { regexp.append("(?=.*").append(word).append(")"); }

Danach verwenden wir die matcher () -Methode, um die Vorkommen zu finden () :

public static boolean containsWordsPatternMatch(String inputString, String[] words) { StringBuilder regexp = new StringBuilder(); for (String word : words) { regexp.append("(?=.*").append(word).append(")"); } Pattern pattern = Pattern.compile(regexp.toString()); return pattern.matcher(inputString).find(); }

Aber reguläre Ausdrücke haben auf Kosten der Leistung. Wenn wir mehrere Wörter nachschlagen müssen, ist die Leistung dieser Lösung möglicherweise nicht optimal.

6. Verwenden von Java 8 und List

Und schließlich können wir die Stream-API von Java 8 verwenden. Aber lassen Sie uns zuerst einige kleinere Transformationen mit unseren Anfangsdaten durchführen:

List inputString = Arrays.asList(inputString.split(" ")); List words = Arrays.asList(words);

Jetzt ist es Zeit, die Stream-API zu verwenden:

public static boolean containsWordsJava8(String inputString, String[] words) { List inputStringList = Arrays.asList(inputString.split(" ")); List wordsList = Arrays.asList(words); return wordsList.stream().allMatch(inputStringList::contains); }

Die obige Operations-Pipeline gibt true zurück, wenn die Eingabezeichenfolge alle unsere Schlüsselwörter enthält.

Alternativ können wir einfach die Methode includesAll () des Collections-Frameworks verwenden , um das gewünschte Ergebnis zu erzielen:

public static boolean containsWordsArray(String inputString, String[] words) { List inputStringList = Arrays.asList(inputString.split(" ")); List wordsList = Arrays.asList(words); return inputStringList.containsAll(wordsList); }

However, this method works for whole words only. So, it would find our keywords only if they're separated with whitespace within the text.

7. Using the Aho-Corasick Algorithm

Simply put, the Aho-Corasick algorithm is for text searching with multiple keywords. It has O(n) time complexity no matter how many keywords we're searching for or how long the text length is.

Let's include the Aho-Corasick algorithm dependency in our pom.xml:

 org.ahocorasick ahocorasick 0.4.0 

First, let's build the trie pipeline with the words array of keywords. For that, we'll use the Trie data structure:

Trie trie = Trie.builder().onlyWholeWords().addKeywords(words).build();

After that, let's call the parser method with the inputString text in which we would like to find the keywords and save the results in the emits collection:

Collection emits = trie.parseText(inputString);

And finally, if we print our results:

emits.forEach(System.out::println);

For each keyword, we'll see the start position of the keyword in the text, the ending position, and the keyword itself:

0:4=hello 13:20=Baeldung

Finally, let's see the complete implementation:

public static boolean containsWordsAhoCorasick(String inputString, String[] words) { Trie trie = Trie.builder().onlyWholeWords().addKeywords(words).build(); Collection emits = trie.parseText(inputString); emits.forEach(System.out::println); boolean found = true; for(String word : words) { boolean contains = Arrays.toString(emits.toArray()).contains(word); if (!contains) { found = false; break; } } return found; }

In this example, we're looking for whole words only. So, if we want to match not only the inputString but “helloBaeldung” as well, we should simply remove the onlyWholeWords() attribute from the Trie builder pipeline.

Beachten Sie außerdem, dass wir auch die doppelten Elemente aus der emits- Auflistung entfernen , da möglicherweise mehrere Übereinstimmungen für dasselbe Schlüsselwort vorhanden sind.

8. Fazit

In diesem Artikel haben wir gelernt, wie Sie mehrere Schlüsselwörter in einer Zeichenfolge finden. Darüber hinaus haben wir Beispiele unter Verwendung des Kern-JDK sowie der Aho-Corasick- Bibliothek gezeigt.

Wie üblich ist der vollständige Code für diesen Artikel auf GitHub verfügbar.