Abstract
Per molti restano arcane e contorte sequenze di simboli, ma una volta
imparate ad usarle diventa quasi impossibile pensare di risolvere alcuni
problemi, in maniera compatta e veloce, senza di esse.
Data di stesura: 22/09/2002
Data di pubblicazione:
22/09/2002
Ultima modifica: 04/04/2006
Per gli "amici" sono le "regex", per il resto del mondo sono "quella
sequenza astrusa di caratteri assolutamente senza senso".
A cosa servono?
La risposta è semplice: pattern matching.
Ovvero la ricerca (matching) di sottostringhe (patterns) all'interno di un
testo o, con alcune precauzioni, anche all'interno di una porzione di dati
binari.
C'è da notare che solitamente le regex permettono sia la ricerca che la
successiva sostituzione del pattern con una sequenza di caratteri data.
Cosa sono?
Le regular expression sono un formalismo, solitamente sono una sequenza di
caratteri atte a descrivere un insieme di stringhe.
carattere
A meno di caratteri speciali riservati per le regex, che è
necessario far precedere da uno '\', costituisce un pattern da
rintracciare così com'è.
^
Identifica l'inzio della riga
$
Identifica la fine della riga
[...]
Tra parentesi quadre viene identificato un insieme di caratteri, il
match è positivo quando almeno uno fra questi viene trovato.
Se viene usato un '-' fra due caratteri questo viene interpretato com un
intervallo che comprende tutti i valori ASCII fra loro, estremi inclusi.
.
Un carattere qualsiasi.
?
Match di zero o una volta del pattern che precede il carattere '?'.
*
Match di zero o più volte del pattern che precede il carattere '*'.
+
Match di una o più volte del pattern che precede il carattere '+'.
|
Match del pattern che lo precede o di quello che segue.
(...)
Le parentesi tonde raggruppano uno o più patterns e rispettivi
modificatori.
Semplice match di una data: [0-9]+/[0-9A-Za-z]+/[0-9]+
Una linea intera: ^.*$
Un file con nome ed estensione: ^(.+)\.(.+)$
Con un applet di esempio, proveniente
dal sito del progetto
gnu.regexp per
Java, potete fare alcune prove liberamente senza dover scrivere nulla al di
fuori della regex.
Perché e quando conviene usarle?
Il perché dell'utilità e evidente, una regex è una descrizione compatta
di un insieme: è in grado di catturare una serie di varianti che
normalmente richiederebbero la scrittura di decine di righe di codice ad
hoc. Senza dimenticare che modificare, correggere, estendere un codice
per un pattern matching ad hoc tende ad essere un problema più
complicato di una regex, per quanto complessa essa sia.
Spesso con una regex mediamente complessa si riesce ad evitare di dover
scrivere diverse centinaia di righe di codice (intricato per via di
numerosi blocchi condizionali).
#!/usr/bin/perl -w
foreach $var (@ARGV) {
printf("'%s' %d\n",
$var,
$var =~ /[1-5] settembre 20[0-9][0-9]/);
}
Questa semplice regex, evidenziata sopra in grassetto, ricerca all'interno
della variabile $var tutte le sequenze di caratteri che comincino coi
numeri da 1 a 5, seguiti da " settembre 20" e terminate con due cifre fra 0
e 9.
La stessa cosa in C potrebbe essere scritta senza l'uso della libregex
così:
Il codice marcato in grassetto equivale alla regex del programma in perl
precedente. È più che evidente che il controllo di correttezza su un
algoritmo di matching ad hoc è più complesso della lettura ed
interpretazione dei formalismi di una regex.
Quando NON conviene usarle?
Le regex devono essere interpretate, ciò comporta l'uso di una certa
quantità di spazio (memoria) e tempo.
Per problemi di matching molto semplici è inutile e dispendioso l'utilizzo
di una regular expression dove una strcmp o una memcmp (nel caso di C)
possono fare gran parte del lavoro in maniera più efficiente.
Conclusioni
Questa prima parte sulle Regular Expressions termina qui, nel prossimo
articolo verranno presi in considerazione vari linguaggi ed il modo in cui
le regex sono implementate e la loro integrazione con il linguaggio ospite.
Informazioni sull'autore
Marco Lamberto, laureato in Informatica presso la Statale di Milano, con diversi anni di esperienza sistemistica, di sicurezza e sviluppo prevalentemente in ambienti UNIX (Linux in primis) con linguaggi come C, Java, Perl, PHP, XML, HTML, ...
"Mastering Regular Expressions" è una lettura obbligatoria per chiunque
volesse approfondire all'estremo la conoscenza delle RegEx (features
avanzate, limitazioni, ottimizzazioni) facendo molta attenzione alle
loro implementazioni specifiche.
http://www.oreilly.com/catalog/regex/
Man page del perl sulle regular expressions. Suggerita la lettura anche
di "perlrequick" e "perlretut", i riferimenti possono essere trovati in
fondo al documento nella sezione "SEE ALSO".
http://www.perldoc.com/perl5.8.0/pod/perlre.html