Capitolo successivo Capitolo precedente Indice

79. Espressioni regolari

L'espressione regolare è un modo per definire la ricerca di stringhe attraverso un modello di comparazione. Viene usato da diversi programmi di utilità, ma non tutti aderiscono agli stessi standard. Nelle sezioni seguenti viene riportata la traduzione della maggior parte della definizione utilizzata nella documentazione BSD che a sua volta si riferisce allo standard POSIX 1003.2. Si tratta precisamente del documento re_format(7).

79.1 Introduzione

Un'espressione regolare, come definita nello standard POSIX 1003.2, può essere in due forme: espressioni regolari estese (extended) ed elementari (basic). Le seconde sono obsolete ed esistono soprattutto per mantenere la compatibilità con il passato in alcuni vecchi programmi.

79.2 Espressioni regolari estese

Una espressione regolare è composta da una o più diramazioni (branch) non vuote, separate da una barra verticale (|). Ciò corrisponde a tutto ciò che corrisponde ad almeno uno dei rami.

Un ramo è fatto da uno o più elementi (peace) concatenati. La corrispondenza si verifica se tutti gli elementi del ramo corrisponodono, nella sequenza in cui sono.

Un elemento è un atomo che può essere seguito da un simbolo *, +, ? o da un contenitore (bound). Un atomo seguito da * corrisponde a una sequenza di zero o più corrispondenze dell'atomo stesso. Un atomo seguito da + corrisponde a una sequenza di una o più corrispondenze dell'atomo stesso. Un atomo seguito da ? corrisponde a una sequenza di zero o al massimo una corrispondenza dell'atomo stesso.

Un contenitore inizia con il simbolo { seguito da un numero decimale senza segno, eventualmente seguito da una virgola (,), eventualmente seguita da un altro numero decimale senza segno, e termina con il simbolo }. I numeri vanno da zero (incluso) a un valore massimo che di norma è 255 e se ne vengono indicati due, il primo non può essere superiore al secondo. Un atomo seguito da un contenitore nel quale appaiono due numeri i e j corrisponde a un sequenza che va da i a j (estremi inclusi) volte l'atomo stesso.

Un atomo è una espressione regolare racchiusa tra parentesi tonde, un set vuoto di parentesi tonde, (), corrispondente alla stringa nulla, una espressione tra parentesi quadre, un punto (corrispondente a ogni singolo carattere), l'accento circonflesso (corrispondente alla stringa nulla all'inizio di una riga), il dollaro (corrispondente alla stringa nulla alla fine di una riga), una barra inclinata rovescia (\) seguita da uno dei caratteri ^.[$()|+?{\ (corrispondente a quel carattere preso come un carattere normale), una barra inclinata rovescia (\) seguita da un qualunque altro carattere (corrispondente a quel carattere preso come carattere normale), o un carattere singolo senza altri significati particolari (corrispondente al carattere stesso).

In generale l'affermazione per gui il simbolo \ seguito da un carattere normale corrisponde al carattere stesso, non è sempre vera. Molte implementazioni utilizzano delle sequenze di escape formate da \ seguito da un altro simbolo per rappresentare un tipo differente di carattere.
Un simbolo { che non sia seguito da un numero è un carattere normale. Una espressione regolare non può terminare con il simbolo \.

Una espressione tra parentesi quadre (bracket expression) è un elenco di caratteri racchiusi tra parentesi quadre. Normalmente corrisponde a ogni singolo carattere contenuto nell'elenco. Se l'elenco inizia con l'accento circonflesso, corrisponde a ogni carattere che non appartiene al resto dell'elenco. Se all'interno dell'elenco due caratteri sono separati da un trattino (-), questa è una abbreviazione per l'intero intervallo di caratteri tra i due (inclusi) nella collating sequence, per esempio [0-9] in ASCII corrisponde a ogni cifra numerica decimale. Non è ammissibile che due intervalli condividano un punto terminale, per esempio a-c-e. Gli intervalli sono strettamente dipendenti dalla collating sequence e i programmi portabili dovrebbero evitare di farne affidamento.

Per includere nell'elenco un carattere ] con valore letterale, va messo all'inizio dell'elenco (eventualmente preceduto dall'accento circonflesso). Per includere un carattere - letterale, deve essere il primo o l'ultimo, o l'elemento finale di un intervallo. Per usare un carattere - letterale come elemento iniziale di un intervallo, lo si deve racchiudere tra [. e .] per fare in modo che diventi un collating element.

Una collating sequence è letteralmente una sequenza di collazione che indica l'ordine con cui sono stati raccolti determinati elementi. Per esempio, le lettere dell'alfabeto sono raccolte in un certo ordine, per cui la lettera C è dopo la B e prima della D. In questo caso, l'ordine si riferisce alla sequenza della codifica ASCII o di quella effettivamente utilizzata. Un collating element è un elemento della collazione, cioè un elemento del gruppo per il quale è stato definito un certo ordine.
Con l'eccezione di queste e alcune combinazioni utilizzando il simbolo [, tutti gli altri caratteri speciali, compreso \, perdono il loro significato speciale all'interno delle espressioni tra parentesi quadre.

All'interno di una espressione tra parentesi quadre, un collating element (un carattere, una sequenza multicarattere che si comporta come se fosse un singolo carattere, o un nome di collating sequence per entrambi) racchiuso tra [. e .] sta per la sequenza di caratteri di quel collating element. La sequenza è un singolo elemento dell'elenco della espressione tra parentesi quadre. Una espressione tra parentesi quadre contenente un collating element multicarattere può così corrispondere a più di un carattere, per esempio se la collating sequence include un collating element ch, allora l'espressione regolare [[.ch.]]*c corrisponde ai primi cinque caratteri di chchcc

Cioè corrisponde alla porzione chchc.

All'interno di una espressione tra parentesi quadre, un collating element racchiuso tra [= e =] è una classe di equivalenza, che sta per la sequenza di caratteri di collating element equivalenti a quello, incluso se stesso. (Se non ci sono ci sono altri collating element equivalenti, il trattamento è lo stesso della inclusione tra [. e .].) Per esempio, se o e ô sono i membri di una classe di equivalenza, allora [[=o=]], [[=ô=]] e [oô] sono tutti sinonimi. Una classe di equivalenza non può essere l'elemento conclusivo di un intervallo.

All'interno di una espressione tra parentesi quadre, il nome di una classe di caratteri (character class) tra [: e :] sta per l'elenco di tutti i caratteri che appartengono a quella classe. Le classi di caratteri standard sono:

Una localizzazione può fornirne delle altre. Una classe di caratteri non può essere usata come punto finale di un intervallo.

Nel caso in cui una espressione regolare possa corrispondere a più di una sottostringa di una data stringa, l'espressione regolare corrisponde a quella che inizia prima nella stringa. Se una espressione regolare può corrispondere a più di una sottostringa a partire da quel punto, la corrispondenza si avrà per quella più lunga. Anche le sottoespressioni corrispondono alla sottostringa più lunga, ciò sottomesso al fatto che la corrispondenza globale sia la più lunga possibile. Da notare che le sottoespressioni di livello più alto prendono quindi la precedenza sulle loro componenti sottoespressioni di livello inferiore.

Le dimensioni della corrispondenza sono misurate in caratteri, non in collating element. Una stringa nulla è considerata più lunga di una mancata corrispondenza. Per esempio, bb* corrisponde ai tre caratteri nel centro di abbbc, (wee|week)(knights|nights) corrisponde a tutti i dieci caratteri di weeknights, dove (.*).* viene confrontata con abc l'espressione tra parentesi corrisponde a tutti e tre i caratteri, e quando (a*)* viene confrontata con ab sia l'espressione regolare completa che la sottoespressione tra parentesi corrispondono alla stringa nulla.

Se viene specificato un tipo di corrispondenza indipendente dalla differenza tra maiuscole e minuscole, l'effetto è come quello che si avrebbe se tutte le distinzioni tra maiuscole e minuscole scomparissero dall'alfabeto. Quando una lettera dell'alfabeto che esiste sia in maiuscolo che minuscolo appare come un carattere normale al di fuori di una espressione tra parentesi quadre, viene di fatto trasformata in una espressione tra parentesi quadre contenente entrambe le lettere, per esempio x diventa [xX]. Quando questa appare all'interno di una espressione tra parentesi quadre, tutte le coppie sono aggiunte all'interno dell'espressione, così che [x] diventa [xX] e [^x] diventa [^xX].

Non viene posto alcun limite alla lunghezza delle espressioni regolari. I programmi fatti per essere portabili non dovrebbero impiegare espressioni regolari più lunghe di 256 caratteri, dal momento che una implementazione può rifiutare di accettare tali espressioni regolari pur rimanendo aderente allo standard POSIX.

79.3 Espressioni regolari elementari (obsolete)

Le espressioni regolari elementari (basic) differiscono in molti aspetti. I simboli |, +, e ? sono caratteri normali e non c'è un equivalente per la loro funzionalità. I delimitatori per i contenitori sono \{ e \}, con { e } per conto loro trattati come caratteri normali. le parentesi per le sottoespressioni annidate sono \( e \), con ( e ) per conto loro trattati come caratteri normali. Il simbolo ^ è un carattere normale a eccezione di quando si trova all'inizio di una espressione regolare o all'inizio di una sottoespressione tra parentesi, e * è un carattere normale se appare all'inizio di una espressione regolare o all'inizio di una sottoespressione tra parentesi (eventualmente dopo un ^ iniziale). Infine, c'è un nuovo tipo di atomo, un back reference: \ seguito da una cifra decimale d diversa da zero corrisponde alla stessa sequenza di caratteri cui corrisponde la d-esima sottoespressione tra parentesi (numerando le sottoespressioni attraverso la posizione delle loro parentesi aperte, da sinistra a destra), cosicché (per esempio) \([bc]\)\1 corrisponde a bb o cc, ma non a bc.


Capitolo successivo Capitolo precedente Indice