Hvordan teller antall kamper for en Regex?

1. Oversikt

Regulære uttrykk kan brukes til en rekke tekstbehandlingsoppgaver, for eksempel ordtellingalgoritmer eller validering av tekstinndata.

I denne veiledningen tar vi en titt på hvordan du bruker vanlige uttrykk til telle antall treff i litt tekst.

2. Bruk sak

La oss utvikle en algoritme som er i stand til teller hvor mange ganger en gyldig e-post vises i en streng.

For å oppdage en e-postadresse, bruker vi et enkelt mønster for vanlig uttrykk:

([a-z0-9 _.-] +) @ ([a-z0-9 _.-] + [a-z])

Merk at dette er et trivielt mønster kun for demonstrasjonsformål, da den faktiske regexen for å matche gyldige e-postadresser er ganske kompleks.

Vi trenger dette vanlige uttrykket inne i Mønster objekt slik at vi kan bruke det:

Mønster EMAIL_ADDRESS_PATTERN = Mønster.kompilere ("([a-z0-9 _.-] +) @ ([a-z0-9 _.-] + [a-z])");

Vi ser på to hovedtilnærminger, hvorav den ene avhenger av bruk av Java 9 eller nyere.

For eksempelteksten vår vil vi prøve å finne de tre e-postmeldingene i strengen:

"Du kan kontakte meg via [email protected], [email protected] og [email protected]"

3. Tellekamper for Java 8 og eldre

For det første, la oss se hvordan vi teller kampene ved hjelp av Java 8 eller eldre.

En enkel måte å telle kampene på er å gjenta over finne metoden for Matcher klasse. Denne metoden prøver å finn neste sekvens av inngangssekvensen som samsvarer med mønsteret:

Matcher countEmailMatcher = EMAIL_ADDRESS_PATTERN.matcher (TEXT_CONTAINING_EMAIL_ADDRESSES); int-antall = 0; mens (countEmailMatcher.find ()) {count ++; }

Ved hjelp av denne tilnærmingen finner vi tre kamper, som forventet:

assertEquals (3, count);

Merk at finne metoden nullstiller ikke Matcher etter hvert treff som er funnet - det starter igjen med tegnet etter slutten av forrige sekvens matchet, så det fungerer ikke å finne overlappende e-postadresser.

La oss for eksempel vurdere dette eksemplet:

String OVERLAPPING_EMAIL_ADDRESSES = "Prøv å kontakte oss på [email protected] @ baeldung.com, [email protected]"; Matcher countOverlappingEmailsMatcher = EMAIL_ADDRESS_PATTERN.matcher (OVERLAPPING_EMAIL_ADDRESSES); int-antall = 0; mens (countOverlappingEmailsMatcher.find ()) {count ++; } assertEquals (2, count);

Når regex prøver å finne treff i det gitte Streng, først vil den finne “[email protected]” som en kamp. Siden det ikke er noen domenedel foran @, blir ikke markøren tilbakestilt og den andre “@ Baeldung.com” blir ignorert. Når du går videre, vil den også vurdere “[email protected]” som den andre kampen:

Som vist ovenfor har vi bare to kamper i det overlappende e-posteksemplet.

4. Telle treff for Java 9 og senere

Men hvis vi har en nyere versjon av Java tilgjengelig, kan vi bruke resultater metoden for Matcher klasse. Denne metoden, lagt til i Java 9, returnerer en sekvensiell strøm av kampresultater, slik at vi lettere kan telle kampene:

lang telling = countEmailMatcher.results () .count (); assertEquals (3, count);

Som vi så med finne, den Matcher tilbakestilles ikke mens behandlingen av strømmen fra resultater metode. Tilsvarende resultater metoden vil heller ikke fungere for å finne treff som overlapper hverandre.

5. Konklusjon

I denne korte artikkelen har vi lært hvordan vi teller kampene til et vanlig uttrykk.

For det første lærte vi å bruke finne metode med en samtidig som Løkke. Så så vi hvordan den nye Java 9-streamingmetoden lar oss gjøre dette med mindre kode.

Som alltid er kodeeksemplene tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found