Come contare il numero di corrispondenze per un'espressione regolare?

1. Panoramica

Le espressioni regolari possono essere utilizzate per una varietà di attività di elaborazione del testo, come algoritmi di conteggio parole o convalida di input di testo.

In questo tutorial, daremo un'occhiata a come utilizzare le espressioni regolari per contare il numero di corrispondenze in un testo .

2. Caso d'uso

Sviluppiamo un algoritmo in grado di contare quante volte un'e-mail valida appare in una stringa .

Per rilevare un indirizzo e-mail, utilizzeremo un semplice modello di espressione regolare:

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

Nota che questo è un modello banale solo a scopo dimostrativo, poiché la regex effettiva per la corrispondenza di indirizzi email validi è piuttosto complessa.

Avremo bisogno di questa espressione regolare all'interno di un oggetto Pattern in modo da poterla utilizzare:

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

Vedremo due approcci principali, uno dei quali dipende dall'utilizzo di Java 9 o successivo.

Per il nostro testo di esempio, proveremo a trovare le tre email nella stringa:

"You can contact me through [email protected], [email protected], and [email protected]"

3. Conteggio delle corrispondenze per Java 8 e versioni precedenti

Per prima cosa, vediamo come contare le corrispondenze utilizzando Java 8 o versioni precedenti.

Un modo semplice per contare le corrispondenze consiste nell'iterare il metodo find della classe Matcher . Questo metodo tenta di trovare la successiva sottosequenza della sequenza di input che corrisponde al modello :

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

Utilizzando questo approccio, troveremo tre corrispondenze, come previsto:

assertEquals(3, count);

Nota che il metodo find non reimposta il Matcher dopo ogni corrispondenza trovata: riprende a partire dal carattere dopo la fine della sequenza precedente abbinata, quindi non funzionerebbe per trovare indirizzi email sovrapposti.

Ad esempio, consideriamo questo esempio:

String OVERLAPPING_EMAIL_ADDRESSES = "Try to contact us at [email protected]@baeldung.com, [email protected]"; Matcher countOverlappingEmailsMatcher = EMAIL_ADDRESS_PATTERN.matcher(OVERLAPPING_EMAIL_ADDRESSES); int count = 0; while (countOverlappingEmailsMatcher.find()) { count++; } assertEquals(2, count);

Quando la regex cerca di trovare corrispondenze nella stringa data , prima troverà "[email protected]" come corrispondenza. Poiché non esiste una parte di dominio che precede @, il marcatore non verrà ripristinato e il secondo "@ baeldung.com" verrà ignorato. Andando avanti, considererà anche "[email protected]" come la seconda corrispondenza:

Come mostrato sopra, abbiamo solo due corrispondenze nell'esempio di posta elettronica sovrapposta.

4. Conteggio delle corrispondenze per Java 9 e versioni successive

Tuttavia, se abbiamo una versione più recente di Java disponibili, possiamo utilizzare il risultati metodo della Matcher di classe. Questo metodo, aggiunto in Java 9, restituisce un flusso sequenziale di risultati delle corrispondenze, permettendoci di contare le partite più facilmente:

long count = countEmailMatcher.results() .count(); assertEquals(3, count);

Come abbiamo visto con find , Matcher non viene ripristinato durante l'elaborazione del flusso dal metodo dei risultati . Allo stesso modo, il metodo dei risultati non funzionerebbe nemmeno per trovare corrispondenze che si sovrappongono.

5. conclusione

In questo breve articolo, abbiamo imparato come contare le corrispondenze di un'espressione regolare.

In primo luogo, abbiamo imparato come utilizzare il metodo find con un ciclo while . Poi abbiamo visto come il nuovo metodo di streaming Java 9 ci permette di farlo con meno codice.

Come sempre, gli esempi di codice sono disponibili su GitHub.