Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Regular expressions in Java

Scopriamo cosa sono le Regular expressions (espressioni regolari) e qual è la sintassi corretta per il loro utilizzo nelle applicazioni basate sul linguaggio Java.
Scopriamo cosa sono le Regular expressions (espressioni regolari) e qual è la sintassi corretta per il loro utilizzo nelle applicazioni basate sul linguaggio Java.
Link copiato negli appunti

Uno dei successi non particolarmente celebrati nei processi di standardizzazione in Computer Science sono state le regular expressions. Una regular expression è una formula che specifica classi di stringhe e che viene realizzata utilizzando un particolare linguaggio.

Pattern

Sappiamo che una stringa è costituita da una sequenza di simboli, quindi, da un punto di vista formale, una regular expression è una notazione algebrica per caratterizzare insiemi di stringhe. Le regular expressions definiscono un vero e proprio linguaggio formale che viene utilizzato per effettuare ricerche specifiche all'interno di un testo.

Da un punto di vista pratico, definire una regular expression, consiste nello specificare un pattern, ovvero il formato di ciò che vogliamo cercare all'interno di un testo. L'esecuzione della regular expression restituirà come output le occorrenze di stringhe contenute all'interno del testo stesso che sono in match con il pattern definito.

Java regex per le regular expressions

In Java l'utilizzo delle regular expressions avviene attraverso le classi java.util.regex.Matcher e java.util.regex.Pattern.

Un primo semplice esempio. Vogliamo cercare un stringa all'interno di un testo:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
..
Pattern pattern = Pattern.compile("regular");
Matcher matcher = pattern.matcher("A regular expression can specify search strings as well as define a language in a formal way");
while(matcher.find()){
System.out.print(matcher.group()+"-");
System.out.print(matcher.start()+"-");
System.out.println(matcher.end());
}

Con la classe Pattern definiamo il pattern per la ricerca puntuale di occorrenze della stringa regular all'interno del testo di input specificato nel metodo matcher().

Successivamente, utilizzando il metodo find(), iteriamo su tutte le occorrenze individuate stampando l'occorrenza stessa, l'indice della posizione del suo primo carattere all'interno del testo (metodo start()), e l'offset, a partire dall'inizio del testo, del carattere che segue la posizione dell'ultimo carattere dell'occorrenza corrente. Cosi, l'esempio mostrato, produrrà in outptut:

regular-2-9

Le regular expressions sono case sensitive, questo significa, ad esempio, che la ricerca del pattern Regular nel codice precedente non avrebbe prodotto alcun risultato. Per disattivare questo comportamento è sufficiente utilizzare la seguente definizione di pattern:

Pattern pattern = Pattern.compile("Regular", Pattern.CASE_INSENSITIVE);

Java pattern: gli operatori

Proseguiamo analizzando gli operatori fondamentali che è necessario conoscere per iniziare a definire dei pattern di una certa complessità:

\d match any digit
\D match any non digit
\w match any alphanumeric/underscore
\W match any non alphanumeric
\s match any whitespace
\S match any non whitespace

Utilizziamo i primi due operatori per estrarre cifre decimali e simboli diversi da esse:

Pattern pattern = Pattern.compile("\\d");
Matcher matcher = pattern.matcher("The number 8 and 8x10=80");
while(matcher.find()){
System.out.print(matcher.group()+"-");
System.out.print(matcher.start()+"-");
System.out.println(matcher.end());
}

Che produrrà come output:

Occorrenza=8-Start=11-End=12
Occorrenza=8-Start=17-End=18
Occorrenza=1-Start=19-End=20
Occorrenza=0-Start=20-End=21
Occorrenza=8-Start=22-End=23
Occorrenza=0-Start=23-End=24

Mentre utilizzando il pattern \\D avremo in stampa tutto ciò che non è una cifra decimale del testo di input.

Se proviamo ad utilizzare il pattern \\w vedremo invece stampati solo caratteri alfanumerici.

Come si può facilmente dedurre, l'utilizzo dello \s permette l'individuazione di tutti i caratteri di tipo whitespace (spazi, ritorni a capo, tabulazioni..), nel caso in esame quattro occorrenze di spazi bianchi.

Riprendendo il testo di input dell'esempio precedente, proviamo ad estrarre tutti i numeri interi positivi contenuti al suo interno. Questa operazione è facilmente ottenibile
utilizzando gli operatori di cardinalità:

+ one more occurences
* zero or more occurences
? exactly zero or one occurence

In particolare, utilizzando l'operatore + ricerchiamo sequenze costituite da una o più cifre. Cosi con il pattern:

Pattern pattern = Pattern.compile("\\d+");

Otteniamo in output:

Occorenza=8-Start=11-End:12
Occorenza=8-Start=17-End:18
Occorenza=10-Start=19-End:21
Occorenza=80-Start=22-End:24

Regular expression: le sostituzioni nei testi

Un'importante caratteristica delle regular expression è la possibilità di effettuare sostituzioni all'interno del testo. Ad esempio supponiamo di voler sostituire ad ogni numero intero positivo il numero stesso racchiuso dal tag HTML b. Per realizzare questa operazioni sono sufficienti le seguenti istruzioni:

Pattern pattern = Pattern.compile("(\\d+)");
Matcher matcher = pattern.matcher("The number 8 and 8x10=80");
System.out.println(matcher.replaceAll("<b>$1</b>"));

Ottenendo come risultato:

The number <b>8</b> and <b>8</b>x<b>10</b>=<b>80</b><

Facciamo notare l'utilizzo delle parentesi nel pattern iniziale ed il simbolo $1 per la corretta identificazione del gruppo corrente. Il punto rappresenta un carattere speciale denominato jolly, esso indica la presenza di un carattere qualsiasi. Se scrivessimo un pattern del tipo:

Pattern pattern = Pattern.compile(".0");
Matcher matcher = pattern.matcher("The number 8 and 8x10=80");
while(matcher.find()){
System.out.print(matcher.group()+" ");
}

Otterremmo in stampa: 10 80. Abbiamo in sostanza chiesto tutte le sequenze di due caratteri di cui il secondo è la cifra zero mentre il primo può essere un qualsiasi carattere.

Insiemi e parentesi

Un altro aspetto importante è la possibilità di definire insiemi attraverso le parentesi quadre. Supponiamo di voler definire un semplice validatore di indirizzi mail:

Pattern pattern = Pattern.compile("[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z]+");
Matcher matcher = pattern.matcher("alias21@dominio.it");
System.out.println(matcher.matches());
Matcher matcher = pattern.matcher("alias21@dominioit");
System.out.println(matcher.matches());

La regular expression definita è sicuramente più complessa di quelle viste in precedenza, con essa stiamo dicendo, attraverso l'utilizzo delle parentesi quadre, che un indirizzo email deve essere composto da un sequenza di uno o più simboli appartenenti all'insieme che ha per elementi i caratteri dell'alfabeto e le cifre decimali, seguito dal simbolo @ a cui fa seguito un altro insieme simile al primo.

Si continua utilizzando il punto, che in questo caso non rappresenta il carattere jolly grazie allo slash che lo precede, ed un sequenza finale i cui simboli appartengono all'insieme dei caratteri dell'alfabeto.

Conclusioni sulle espressioni regolari

Con il presente approfondimento si sono introdotti i concetti fondamentali per iniziare a costruire semplici regular expressions, le caratteristiche di cui sono dotate non si esauriscono ovviamente con quanto analizzato in precedenza, esistono molti altri operatori che consentono la definizione di operazioni e pattern sempre più complessi.

Ti consigliamo anche