Kontroller, om en streng indeholder flere nøgleord i Java

1. Introduktion

I denne hurtige vejledning vi finder ud af, hvordan man finder flere ord inde i en streng.

2. Vores eksempel

Lad os antage, at vi har strengen:

String inputString = "hej der, Baeldung";

Vores opgave er at finde ud af, om inputString indeholder "Hej" og “Baeldung” ord.

Så lad os sætte vores nøgleord i en matrix:

String [] ord = {"hej", "Baeldung"};

Desuden er rækkefølgen af ​​ordene ikke vigtig, og kampene skal være store og små bogstaver.

3. Brug String.contains ()

Som en start, vi viser, hvordan du bruger String.contains () metode til at nå vores mål.

Lad os løbe over nøgleordsarrayet og kontrollere forekomsten af ​​hvert element inden i inputString:

offentlig statisk boolsk indeholderWords (String inputString, String [] items) {boolsk fundet = sand; for (String item: items) {if (! inputString.contains (item)) {found = false; pause; }} returnering fundet }

Det indeholder() metoden vender tilbage rigtigt hvis den inputString indeholder det givne vare. Når vi ikke har nogen af ​​nøgleordene i vores streng, kan vi stoppe med at bevæge os fremad og returnere en øjeblikkelig falsk.

På trods af at vi har brug for at skrive mere kode, er denne løsning hurtig til simple brugssager.

4. Brug String.indexOf ()

Svarende til den løsning, der bruger String.contains () metode, vi kan kontrollere indekserne for nøgleordene ved hjælp af String.indexOf () metode. Til det har vi brug for en metode, der accepterer inputString og listen over nøgleord:

offentlig statisk boolsk indeholderWordsIndexOf (streng inputString, streng [] ord) {boolsk fundet = sand; for (Stringord: ord) {hvis (inputString.indexOf (ord) == -1) {fundet = falsk; pause; }} returnering fundet }

Det indeks af() metode returnerer indekset for ordet inde i inputString. Når vi ikke har ordet i teksten, vil indekset være -1.

5. Brug af regulære udtryk

Lad os nu bruge et regulært udtryk til at matche vores ord. Til det bruger vi Mønster klasse.

Lad os først definere strengudtrykket. Da vi skal matche to nøgleord, bygger vi vores regex-regel med to lookaheads:

Mønster mønster = Mønster.kompil ("(? =. * Hej) (? =. * Baeldung)");

Og for det generelle tilfælde:

StringBuilder regexp = ny StringBuilder (); for (Strengeord: ord) {regexp.append ("(? =. *"). append (word) .append (")"); }

Derefter bruger vi matcher () metode til finde() forekomsterne:

offentlig statisk boolsk indeholderWordsPatternMatch (String inputString, String [] ord) {StringBuilder regexp = new StringBuilder (); for (Stregord: ord) {regexp.append ("(? =. *"). append (word) .append (")"); } Mønstermønster = Mønster.kompil (regexp.toString ()); retur mønster. matcher (inputString). find (); }

Men, regulære udtryk har en præstationsomkostning. Hvis vi har flere ord at slå op, er ydelsen af ​​denne løsning muligvis ikke optimal.

6. Brug af Java 8 og Liste

Og endelig kan vi bruge Java 8s Stream API. Men lad os først lave nogle mindre transformationer med vores oprindelige data:

Liste inputString = Arrays.asList (inputString.split ("")); Listeord = Arrays.asList (ord);

Nu er det tid til at bruge Stream API:

offentlig statisk boolesk indeholderWordsJava8 (String inputString, String [] ord) {List inputStringList = Arrays.asList (inputString.split ("")); Liste ordListe = Arrays.asList (ord); returner wordsList.stream (). allMatch (inputStringList :: indeholder); }

Operationsrørledningen ovenfor vender tilbage rigtigt hvis inputstrengen indeholder alle vores nøgleord.

Alternativt vi kan simpelthen bruge indeholderAlle () metode til samlingens ramme for at opnå det ønskede resultat:

offentlig statisk boolesk indeholderWordsArray (String inputString, String [] ord) {List inputStringList = Arrays.asList (inputString.split ("")); Liste ordListe = Arrays.asList (ord); returnere inputStringList.containsAll (wordsList); }

Denne metode fungerer dog kun for hele ord. Så det ville kun finde vores nøgleord, hvis de er adskilt med mellemrum i teksten.

7. Brug af Aho-Corasick Algoritme

Kort sagt, den Aho-Corasick algoritme er til tekstsøgning med flere nøgleord. Det har På) tidskompleksitet uanset hvor mange søgeord vi søger efter, eller hvor lang tekstlængden er.

Lad os medtage Aho-Corasick-algoritmeafhængigheden i vores pom.xml:

 org.ahocorasick ahocorasick 0.4.0 

Lad os først bygge trie-rørledningen med ord vifte af nøgleord. Til det bruger vi Trie-datastrukturen:

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

Lad os derefter kalde parsermetoden med inputString tekst, hvor vi gerne vil finde nøgleordene og gemme resultaterne i udsender kollektion:

Samling udsender = trie.parseText (inputString);

Og endelig, hvis vi udskriver vores resultater:

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

For hvert nøgleord ser vi nøgleordets startposition i teksten, slutpositionen og selve nøgleordet:

0: 4 = hej 13: 20 = Baeldung

Lad os endelig se den komplette implementering:

offentlig statisk boolesk indeholderWordsAhoCorasick (String inputString, String [] ord) {Trie trie = Trie.builder (). onlyWholeWords (). addKeywords (ord) .build (); Samling udsender = trie.parseText (inputString); emits.forEach (System.out :: println); boolsk fundet = sand; for (Stringord: ord) {boolsk indeholder = Arrays.toString (emits.toArray ()). indeholder (word); hvis (! indeholder) {fundet = falsk; pause; }} returnering fundet }

I dette eksempel leder vi kun efter hele ord. Så hvis vi ikke kun vil matche inputString men “HejBaeldung” så godt skal vi blot fjerne onlyHele ord () attribut fra Trie bygherrerørledning.

Derudover skal du huske, at vi også fjerner duplikatelementerne fra udsender samling, da der muligvis er flere matches for det samme søgeord.

8. Konklusion

I denne artikel lærte vi, hvordan man finder flere nøgleord i en streng. I øvrigt, vi viste eksempler ved hjælp af kernen JDK såvel som med Aho-Corasick bibliotek.

Som sædvanlig er den komplette kode til denne artikel tilgængelig på GitHub.