Controleer of een string meerdere trefwoorden bevat in Java

1. Invoering

In deze korte tutorial, we zullen zien hoe je meerdere woorden binnen een string kunt detecteren.

2. Ons voorbeeld

Stel dat we de string hebben:

String inputString = "hallo daar, Baeldung";

Het is onze taak om erachter te komen of de inputString bevat de "Hallo" en "Baeldung" woorden.

Dus laten we onze zoekwoorden in een array plaatsen:

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

Bovendien is de volgorde van de woorden niet belangrijk en moeten de overeenkomsten hoofdlettergevoelig zijn.

3. Met behulp van String.contains ()

Om te beginnen we laten zien hoe u de String.contains () methode om ons doel te bereiken.

Laten we de array met trefwoorden doorlopen en controleren of elk item in de inputString:

openbare statische boolean containsWords (String inputString, String [] items) {boolean found = true; for (String item: items) {if (! inputString.contains (item)) {found = false; breken; }} terugkeer gevonden; }

De bevat () methode zal terugkeren waar als het inputString bevat de gegeven item. Als we geen van de trefwoorden in onze reeks hebben, kunnen we stoppen met vooruitgaan en een onmiddellijke false.

Ondanks het feit dat we meer code moeten schrijven, is deze oplossing snel voor eenvoudige gebruikssituaties.

4. Met behulp van String.indexOf ()

Vergelijkbaar met de oplossing die de String.contains () methode, we kunnen de indexen van de trefwoorden controleren met behulp van de String.indexOf () methode. Daarvoor hebben we een methode nodig die de inputString en de lijst met trefwoorden:

openbare statische boolean containsWordsIndexOf (String inputString, String [] woorden) {boolean found = true; for (String word: words) {if (inputString.indexOf (word) == -1) {found = false; breken; }} terugkeer gevonden; }

De index van() methode retourneert de index van het woord in de inputString. Als we het woord niet in de tekst hebben, is de index -1.

5. Gebruik van reguliere expressies

Laten we nu een reguliere expressie gebruiken die overeenkomt met onze woorden. Daarvoor gebruiken we de Patroon klasse.

Laten we eerst de tekenreeksexpressie definiëren. Omdat we twee zoekwoorden moeten matchen, bouwen we onze regex-regel met twee lookaheads:

Patroonpatroon = Pattern.compile ("(? =. * Hallo) (? =. * Baeldung)");

En voor het algemene geval:

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

Daarna gebruiken we de matcher () methode om vind() de gebeurtenissen:

openbare statische boolean containsWordsPatternMatch (String inputString, String [] woorden) {StringBuilder regexp = nieuwe StringBuilder (); for (String word: words) {regexp.append ("(? =. *"). append (word) .append (")"); } Patroonpatroon = Pattern.compile (regexp.toString ()); return pattern.matcher (inputString) .find (); }

Maar, reguliere expressies hebben prestatiekosten. Als we meerdere woorden moeten opzoeken, zijn de prestaties van deze oplossing mogelijk niet optimaal.

6. Met behulp van Java 8 en Lijst

En tot slot kunnen we de Stream API van Java 8 gebruiken. Maar laten we eerst enkele kleine transformaties uitvoeren met onze initiële gegevens:

Lijst inputString = Arrays.asList (inputString.split ("")); Lijstwoorden = Arrays.asList (woorden);

Nu is het tijd om de Stream API te gebruiken:

openbare statische boolean containsWordsJava8 (String inputString, String [] woorden) {List inputStringList = Arrays.asList (inputString.split ("")); List wordsList = Arrays.asList (woorden); return wordsList.stream (). allMatch (inputStringList :: bevat); }

De bovenstaande bewerkingspijplijn keert terug waar als de invoertekenreeks al onze trefwoorden bevat.

Alternatief, we kunnen gewoon de bevatAll () methode van het Collections framework om het gewenste resultaat te bereiken:

openbare statische boolean containsWordsArray (String inputString, String [] woorden) {Lijst inputStringList = Arrays.asList (inputString.split ("")); List wordsList = Arrays.asList (woorden); return inputStringList.containsAll (wordsList); }

Deze methode werkt echter alleen voor hele woorden. Het zou onze zoekwoorden dus alleen vinden als ze in de tekst zijn gescheiden door witruimte.

7. Met behulp van de Aho-Corasick Algoritme

Simpel gezegd, de Aho-Corasick algoritme is voor het zoeken naar tekst met meerdere trefwoorden. Het heeft Aan) tijdscomplexiteit, ongeacht hoeveel zoekwoorden we zoeken of hoe lang de tekstlengte is.

Laten we de afhankelijkheid van het Aho-Corasick-algoritme opnemen in onze pom.xml:

 org.ahocorasick ahocorasick 0.4.0 

Laten we eerst de trie-pijplijn bouwen met de woorden reeks trefwoorden. Daarvoor gebruiken we de Trie-datastructuur:

Trie trie = Trie.builder (). OnlyWholeWords (). AddKeywords (woorden) .build ();

Laten we daarna de parsermethode aanroepen met de inputString tekst waarin we de trefwoorden willen vinden en de resultaten opslaan in de zendt verzameling:

Verzameling zendt = trie.parseText (inputString);

En tot slot, als we onze resultaten afdrukken:

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

Voor elk trefwoord zien we de startpositie van het trefwoord in de tekst, de eindpositie en het trefwoord zelf:

0: 4 = hallo 13:20 = Baeldung

Laten we tot slot de volledige implementatie bekijken:

openbare statische boolean bevatWordsAhoCorasick (String inputString, String [] woorden) {Trie trie = Trie.builder (). onlyWholeWords (). addKeywords (woorden) .build (); Verzameling zendt = trie.parseText (inputString); emits.forEach (System.out :: println); boolean gevonden = waar; for (String word: words) {boolean contains = Arrays.toString (emits.toArray ()). bevat (woord); if (! bevat) {gevonden = onwaar; breken; }} terugkeer gevonden; }

In dit voorbeeld zoeken we alleen naar hele woorden. Dus als we niet alleen de inputString maar "HalloBaeldung" We moeten ook gewoon de onlyWholeWords () attribuut van het proberen builder-pijpleiding.

Houd er daarnaast rekening mee dat we ook de dubbele elementen verwijderen uit het zendt verzameling, aangezien er mogelijk meerdere overeenkomsten zijn voor hetzelfde trefwoord.

8. Conclusie

In dit artikel hebben we geleerd hoe u meerdere trefwoorden binnen een string kunt vinden. Bovendien, we lieten voorbeelden zien door zowel de core JDK te gebruiken als met de Aho-Corasick bibliotheek.

Zoals gewoonlijk is de volledige code voor dit artikel beschikbaar op GitHub.