Hoe tel je het aantal overeenkomsten voor een Regex?

1. Overzicht

Reguliere expressies kunnen worden gebruikt voor een verscheidenheid aan tekstverwerkingstaken, zoals algoritmen voor het tellen van woorden of validatie van tekstinvoer.

In deze zelfstudie bekijken we hoe u reguliere expressies kunt gebruiken voor tel het aantal overeenkomsten in een tekst.

2. Gebruiksvoorbeeld

Laten we een algoritme ontwikkelen dat in staat is tellen hoe vaak een geldige e-mail in een string voorkomt.

Om een ​​e-mailadres te detecteren, gebruiken we een eenvoudig patroon van reguliere expressies:

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

Merk op dat dit een triviaal patroon is, alleen voor demonstratiedoeleinden, aangezien de eigenlijke regex voor het matchen van geldige e-mailadressen vrij complex is.

We hebben deze reguliere expressie nodig in een Patroon object zodat we het kunnen gebruiken:

Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile ("([a-z0-9 _.-] +) @ ([a-z0-9 _.-] + [a-z])");

We zullen twee hoofdbenaderingen bekijken, waarvan er één afhangt van het gebruik van Java 9 of hoger.

Voor onze voorbeeldtekst zullen we proberen de drie e-mails in de string te vinden:

"U kunt contact met mij opnemen via [e-mail beschermd], [e-mail beschermd] en [e-mail beschermd]"

3. Matches tellen voor Java 8 en ouder

Laten we eerst eens kijken hoe we de overeenkomsten kunnen tellen met Java 8 of ouder.

Een eenvoudige manier om de overeenkomsten te tellen, is door de vind methode van de Matcher klasse. Deze methode probeert zoek de volgende subreeks van de invoersequentie die overeenkomt met het patroon:

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

Met deze aanpak vinden we, zoals verwacht, drie overeenkomsten:

assertEquals (3, count);

Merk op dat de vind methode reset de Matcher na elke gevonden overeenkomst - het begint bij het teken na het einde van de vorige overeenkomende reeks, dus het zou niet werken om overlappende e-mailadressen te vinden.

Laten we bijvoorbeeld eens kijken naar dit voorbeeld:

String OVERLAPPING_EMAIL_ADDRESSES = "Probeer contact met ons op te nemen via [e-mail beschermd] @ baeldung.com, [e-mail beschermd]"; Matcher countOverlappingEmailsMatcher = EMAIL_ADDRESS_PATTERN.matcher (OVERLAPPING_EMAIL_ADDRESSES); int count = 0; while (countOverlappingEmailsMatcher.find ()) {count ++; } assertEquals (2, count);

Wanneer de regex probeert overeenkomsten te vinden in het opgegeven Draad, eerst zal het "[email protected]" als een match vinden. Aangezien er geen domeindeel is voorafgaand aan de @, wordt de markering niet gereset en het tweede "@ Baeldung.com" wordt genegeerd. Verderop zal het ook "[e-mail beschermd]" beschouwen als de tweede overeenkomst:

Zoals hierboven getoond, hebben we slechts twee overeenkomsten in het overlappende e-mailvoorbeeld.

4. Matches tellen voor Java 9 en hoger

Als we echter een nieuwere versie van Java beschikbaar hebben, kunnen we de resultaten methode van de Matcher klasse. Deze methode, toegevoegd in Java 9, retourneert een opeenvolgende stroom matchresultaten, waardoor we de matches gemakkelijker kunnen tellen:

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

Zoals we zagen met vind, de Matcher wordt niet gereset tijdens het verwerken van de stream van het resultaten methode. Evenzo is het resultaten methode zou ook niet werken om overeenkomsten te vinden die elkaar overlappen.

5. Conclusie

In dit korte artikel hebben we geleerd hoe we de overeenkomsten van een reguliere expressie kunnen tellen.

Ten eerste hebben we geleerd hoe we de vind methode met een terwijl lus. Toen zagen we hoe we met de nieuwe streamingmethode Java 9 dit met minder code kunnen doen.

Zoals altijd zijn de codevoorbeelden beschikbaar op GitHub.