Le espressioni regolari rappresentano uno strumento molto potente per lavorare sulle stringhe. Possono essere utilizzate, sia per convalidare i dati, sia per effettuare ricerche all'interno di un testo. La sintassi di questo pseudo-linguaggio è molto flessibile e consente di creare espressioni in base alle proprie esigenze.
Dalla versione 1.4 di Java (in linea con quanto fatto già da PHP, javascript, Ruby e altri), è stato introdotto il package java.util.regex composto dalle classi Pattern e Matcher che permettono di validare una stringa, o ricercare un testo al suo interno, a partire da un'espressione regolare.
Per definire un'espressione regolare è necessario conoscere alcune regole base:
- [...]
Insieme di caratteri validi; - [^...]
Insieme negato di caratteri validi; - -
Intervallo; - &&
Intersezione; - .
Qualunque carattere; - +
Concatenazione; - RE*
Cardinalità multipla (0 o più occorrenze dell'espressione RE); - RE{n}
Cardinalità multipla (esattamente n occorrenze dell'espressione RE); - RE{n,}
Cardinalità multipla (almeno n occorrenze dell'espressione RE); - RE{n,m}
Cardinalità multipla (almeno n occorrenze dell'espressione RE, ma non più di m).
Facciamo alcuni esempi semplici per chiarire meglio le regole:
- [abc]
Espressione che contiene un solo carattere tra a, b, o c; - [^abc]
Espressione che contiene un solo carattere, tutti sono validi, ad esclusione di a, b, o c; - [a-z]
Espressione che contiene un solo carattere tra quelli del range a-z; - [a-d[m-p]]
Espressione che contiene un solo carattere tra quelli del range a-d e del range m-p (unione); - [a-z&&[def]]
Espressione che contiene un solo carattere tra quelli comuni del range a-z e dell'insieme (d, e, f) (intersezione); - [a-z&&[^bc]]
Espressione che contiene un solo carattere tra quelli comuni del range a-z e dell'insieme negato (b, f) (intersezione); - [a-z&&[^m-p]]
Espressione che contiene un solo carattere tra quelli comuni del range a-z e del range negato (m-p) (intersezione).
Esistono anche forme abbreviate per rappresentare un insieme di caratteri. Ad esempio:
- d
Carattere numerico. Corrisponde all'insieme [0-9]; - D
Carattere diverso da un numero. Corrisponde all'insieme [^0-9]; - s
Carattere spazio; - S
Carattere diverso dallo spazio. Corrisponde all'insieme [^s]; - w
Parola alfanumerica. Corrisponde all'insieme [a-zA-Z_0-9]; - W
Parola costituita da caratteri speciali. Corrisponde all'insieme [^w].
Di seguito riportiamo alcune espressioni comunemente utilizzate:
indirizzo email
[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}
data in formato dd/mm/aaaa
(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[-/.](19|20)dd
url http
http://[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}(/S*)?
codice fiscale
[a-zA-Z]{6}dd[a-zA-Z]dd[a-zA-Z]ddd[a-zA-Z]
Adesso che abbiamo i requisiti indispensabili per scrivere un'espressione regolare, vediamo come utilizzare il package java.util.regex per validare le nostre stringhe o ricercare del testo al loro interno.
Le classi principali del package sono le seguenti:
- java.util.regex.Pattern rappresenta l'espressione regolare effettiva. Per ottenere un'istanza della classe Pattern, è necessario invocare il metodo statico compile che accetta come parametro una stringa che rappresenta l'espressione regolare. La classe Pattern dispone anche del metodo statico matches che riceve in input due stringhe, la prima è l'espressione regolare, la seconda è la stringa da validare. Il metodo restituisce un booleano, true se la stringa rispetta il formato, false altrimenti.
- java.util.regex.Matcher è il motore che interpreta i pattern ed esegue le operazioni di match sulla stringa data. Per ottenere un'istanza della classe Matcher, è necessario invocare il metodo statico matcher su un'istanza dell'oggetto Pattern.
- java.util.regex.PatternSyntaxException è l'eccezione che viene sollevata nel momento in cui viene individuato un errore di sintassi nel pattern di una espressione regolare.
Per verificare se una stringa rispetta il formato definito dall'espressione regolare possiamo utilizzare due metodi.
Nel primo caso utilizziamo il metodo statico matches della classe Pattern, passandogli l'espressione regolare e la stringa da validare:
public static boolean check(String regex, String input){
if (Pattern.matches(regex, input))
return true;
else
return false;
}
Nel secondo caso creiamo prima un'istanza della classe Matcher e poi richiamiamo il metodo matcher.
public static boolean check(String regex, String input){
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
return true;
else
return false;
}
È possibile, inoltre, utilizzare il package java.util.regex per ricercare una stringa all'interno di un'altra.
String regex = "[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}";
String input = "pippo@email.it;pluto@email.it;paperino@email.it";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find())
System.out.println(matcher.group());
Il metodo find della classe Matcher, ricerca una sottostringa all'interno della stringa di ingresso che rispetta il formato dell'espressione regolare. Il metodo find funziona come un iterator, cioè aggiorna gli indici ad ogni iterazione. Se eseguiamo l'esempio otterremo come output:
pippo@email.it
pluto@email.it
paperino@email.it