5.13 Le espressioni regolari

Esistono delle sintassi standard (POSIX9 1003.2) che attribuiscono dei significati particolari ad alcune sequenze di caratteri, che vengono utilizzate in particolar modo da strumenti che effettuano ricerche di stringhe in un testo. Tali sequenze di caratteri prendono il nome di espressioni regolari o regular expression (RE). Tali espressioni sono generalmente utilizzate per effettuare ricerche complesse all’interno del testo, ma possono essere utilizzate anche nei file di configurazione delle applicazioni stesse.

Esistono due sintassi diverse per l’interpretazione delle espressioni regolari (v. man page regex(7)): la sintassi di base (o elementare) BRE (Basic Regular Expression) e la sintassi estesa ERE (Extended Regular Expression). La sintassi di base delle espressioni regolari sui sistemi Unix-like è identificata dall’acronimo SRE (Simple Regular Expression), ma per ovviare problemi legati alla localizzazione si tende sempre a far riferimento a BRE o ERE. Il consiglio è quello di utilizzare le ERE poiché le BRE sono considerate obsolete.

Sebbene la loro sintassi sia piuttosto complessa, le RE sono espressioni costruite per mezzo di operatori ed operandi e si interpretano leggendole da sinistra a destra. L’unità fondamentale delle espressioni regolari è il singolo carattere. Quasi tutti i simboli presenti sulla tastiera corrispondono a se stessi, tranne alcuni (^, $, +, ?, ., *, (, ), [, ], {, }, |, \) che assumono invece un particolare significato. Per ottenere il significato di uno dei caratteri sopra riportati è necessario far precedere il carattere stesso dal carattere ‘\’. Ad esempio la sequenza \$ corrisponderà al carattere $, mentre la sequenza \\ corrisponderà al carattere \.

Il significato dei caratteri particolari e delle varie sequenze di caratteri, nelle RE, è riportato di seguito


class------|Significato----------------------------------------------|
[:alnum:]--|L’insieme dei caratteri alfanumerici [0- 9a-zA-Z].-------------|
[:alpha:]  |L’insieme dei caratteri alfabetici [a-zA-Z].                   |
[:cntrl:]  |L’insieme dei caratteri di controllo [\x01- \x7F].              |
[:digit:]  |L’insieme dei caratteri numerici [0-9].                      |
[:[:grloawpehr::]]  |LL’’ininssieiemmee d deeii c cararaattteteriri s atlafambpeatibcilii e mcincuetstcool gili [ sa-p zaz]i. [^\x01-\x20].|
[:print:]  |L’insieme dei caratteri stampabili (classe [:graph:] pi`u gli spazi e la
|        |tabulazione).                                             |
[:[:puspnaccte::]]  |LL’’ininssieiemmeed deeiisi cmarbaotlitedrii sppunatzeiaggtoiraitu [r \an[\!r"#\$t\%x&0'(B)].*+,- ./:;<=>?@[\]^_`{|}~].
[:upper:]  |L’insieme dei caratteri alfabetici maiuscoli [A- Z].             |
[:xdigit:] |L’insieme delle cifre esadecimali [0-9a-fA-F].                  |
[:<:]      |Il carattere nullo all’inizio della RE.                         |
[:>:]-------Il carattere nullo alla-fine-della RE.---------------------------

Tabella 5.16: Possibili insiemi di caratteri utilizzabili nelle espressioni regolari.

Espressioni regolari adiacenti costrituiscono un’espressione regolare che è il risultato della concatenazione delle espressioni regolari originarie.

Per indicare il significato intrinseco dei caratteri utilizzati come metacaratteri è necessario anteporre ad essi il carattere ‘\’.

La precedenza degli operatori della sintassi delle RE è riportata nella tab. 5.17.


Descrizione-----|BRE--------------|ERE-----|
Collation--------|[=-=]-[:-:]-[.-.]-|--------|
Escape         |\                |        |
Bracket expression|[ ]              |        |
Subexpression    |\( \) \n         |( )     |
DuCopnlicacatteionantion    |* \{ \}          |{ } + ? |
Anchoring       |^ $ \< \>        |        |
Alternation-------------------------|--------

Tabella 5.17: Precedenza degli operatori (dall’alto verso il basso).

Ad esempio

 
^pippo  
si riferisce alla stringa ‘pippo’ presente come parte inziale di una riga, mentre

 
pippo$  
a quella presente come parte finale di una riga. Ancora,

 
Daniel[ae]  
si riferisce sia alla stringa ‘Daniela’ che ‘Daniele’. La RE

 
pi..[^a]  
si riferisce ad una stringa che inizia per ‘pi’, contiene altri due caratteri qualunque e l’ultimo carattere è diverso da ‘a’. La RE

 
pi..[a-o]  
si riferisce ad una stringa che inizia per ‘pi’, contiene altri due caratteri qualunque e l’ultimo carattere è compreso (nell’elenco alfabetico) da ‘a’ ad ‘o’, mentre la RE

 
nome[[:digit:]]  
si riferisce ad una stringa che inizia per ‘nome’, seguita da un numero. La RE

 
\(pippo\)+  
si riferisce a qualunque parola che contenga almeno una volta (o più, consecutivamente) la sottostringa ‘pippo’. La RE

 
p\(ipp\)|\(aperin\)o  
si riferisce alle stringhe che iniziano per ‘p’, terminano per ‘o’ e che il resto della stringa sia formato o dalla sottostringa ‘ipp’ o da ‘aperin’: cioè o la stringa ‘pippo’ o ‘paperino’.

Si consiglia di prendere un po’ la mano con la sintassi delle RE, per mezzo del comando grep10. Sempre per le prove, è possibile usare anche il file dizionario /usr/share/dict/words presente su ogni sistema Unix-like, al cui interno sono contenuti, uno per ogni riga, i vocaboli della lingua del sistema operativo.