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.