Sjekk om en streng inneholder flere nøkkelord i Java

1. Introduksjon

I denne raske opplæringen, Vi finner ut hvordan vi kan oppdage flere ord inne i en streng.

2. Vårt eksempel

La oss anta at vi har strengen:

String inputString = "hei, Baeldung";

Vår oppgave er å finne ut om inputString inneholder "Hallo" og “Baeldung” ord.

Så la oss sette nøkkelordene våre i en matrise:

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

Videre er ordrenes rekkefølge ikke viktig, og kampene skal være mellom store og små bokstaver.

3. Bruke String.contains ()

Som en start, vi viser hvordan du bruker String.contains () metode for å nå vårt mål.

La oss løpe over søkeordmatrisen og sjekke forekomsten av hvert element inne i inputString:

offentlig statisk boolsk inneholderWords (String inputString, String [] items) {boolean funnet = true; for (String item: items) {if (! inputString.contains (item)) {funnet = false; gå i stykker; }} retur funnet }

De inneholder () metoden vil komme tilbake ekte hvis inputString inneholder det gitte punkt. Når vi ikke har noen av nøkkelordene i strengen vår, kan vi slutte å gå videre og returnere øyeblikkelig falsk.

Til tross for at vi trenger å skrive mer kode, er denne løsningen rask for enkel brukstilfeller.

4. Bruke String.indexOf ()

I likhet med løsningen som bruker String.contains () metode, vi kan sjekke indeksene til nøkkelordene ved å bruke String.indexOf () metode. For det trenger vi en metode for å godta inputString og listen over nøkkelordene:

offentlig statisk boolsk inneholderWordsIndexOf (String inputString, String [] ord) {boolsk funnet = true; for (Stringord: ord) {if (inputString.indexOf (ord) == -1) {funnet = falsk; gå i stykker; }} retur funnet }

De oversikt over() metoden returnerer indeksen for ordet inne i inputString. Når vi ikke har ordet i teksten, vil indeksen være -1.

5. Bruke vanlige uttrykk

La oss nå bruke et vanlig uttrykk for å matche ordene våre. For det bruker vi Mønster klasse.

La oss først definere strenguttrykket. Da vi må matche to søkeord, bygger vi regex-regelen vår med to lookahead:

Mønster mønster = Mønster.kompilere ("(? =. * Hallo) (? =. * Baeldung)");

Og for den generelle saken:

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

Etter det bruker vi matcher () metode til finne() forekomster:

offentlig statisk boolsk inneholderWordsPatternMatch (String inputString, String [] ord) {StringBuilder regexp = new StringBuilder (); for (Stringord: ord) {regexp.append ("(? =. *"). append (word) .append (")"); } Mønstermønster = Mønster.kompilere (regexp.toString ()); returmønster. matcher (inputString). finn (); }

Men, regulære uttrykk har en ytelseskostnad. Hvis vi har flere ord å slå opp, er ytelsen til denne løsningen kanskje ikke optimal.

6. Bruke Java 8 og Liste

Og til slutt kan vi bruke Java 8s Stream API. Men først, la oss gjøre noen mindre transformasjoner med våre første data:

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

Nå er det på tide å bruke Stream API:

offentlig statisk boolsk inneholderWordsJava8 (streng inputString, streng [] ord) {List inputStringList = Arrays.asList (inputString.split ("")); Liste ordListe = Arrays.asList (ord); return wordsList.stream (). allMatch (inputStringList :: inneholder); }

Operasjonsrørledningen ovenfor kommer tilbake ekte hvis inputstrengen inneholder alle nøkkelordene våre.

Alternativt vi kan ganske enkelt bruke inneholderAlle () metoden for samlingens rammeverk for å oppnå ønsket resultat:

offentlig statisk boolsk inneholderWordsArray (String inputString, String [] ord) {List inputStringList = Arrays.asList (inputString.split ("")); Liste ordListe = Arrays.asList (ord); return inputStringList.containsAll (ordsliste); }

Denne metoden fungerer imidlertid bare for hele ord. Så det vil bare finne søkeordene våre hvis de er skilt med mellomrom i teksten.

7. Bruke Aho-Corasick Algoritme

Enkelt sagt, den Aho-Corasick algoritme er for tekstsøk med flere nøkkelord. Det har På) tidskompleksitet uansett hvor mange søkeord vi søker etter eller hvor lang tekstlengden er.

La oss inkludere Aho-Corasick algoritmeavhengighet i vår pom.xml:

 org.ahocorasick ahocorasick 0.4.0 

La oss først bygge trie-rørledningen med ord rekke søkeord. For det bruker vi Trie-datastrukturen:

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

Etter det, la oss kalle parsermetoden med inputString tekst der vi ønsker å finne nøkkelordene og lagre resultatene i avgir samling:

Samlingen sender ut = trie.parseText (inputString);

Og til slutt, hvis vi skriver ut resultatene våre:

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

For hvert nøkkelord ser vi startposisjonen til nøkkelordet i teksten, sluttposisjonen og selve nøkkelordet:

0: 4 = hei 13: 20 = Baeldung

Til slutt, la oss se den fullstendige implementeringen:

offentlig statisk boolsk inneholderWordsAhoCorasick (String inputString, String [] ord) {Trie trie = Trie.builder (). onlyWholeWords (). addKeywords (ord) .build (); Samlingen sender ut = trie.parseText (inputString); emits.forEach (System.out :: println); boolsk funnet = sant; for (Stringord: ord) {boolsk inneholder = Arrays.toString (emits.toArray ()). inneholder (word); hvis (! inneholder) {funnet = falsk; gå i stykker; }} retur funnet }

I dette eksemplet leter vi bare etter hele ord. Så hvis vi ikke vil matche inputString men “HalloBaeldung” i tillegg bør vi bare fjerne onlyHele ord () attributt fra Trie byggherrerørledning.

I tillegg må du huske at vi også fjerner duplikatelementene fra avgir samling, ettersom det kan være flere treff for det samme søkeordet.

8. Konklusjon

I denne artikkelen lærte vi hvordan vi kan finne flere nøkkelord i en streng. Videre vi viste eksempler ved å bruke kjernen JDK, så vel som med Aho-Corasick bibliotek.

Som vanlig er den komplette koden for denne artikkelen tilgjengelig på GitHub.