regex - espressioni regolari POSIX.2
Le espressioni regolari (dette "ER"), così come definite da
POSIX.2, appaiono in due forme: ER moderne (approssimativamente, quelle di
egrep; POSIX.2 le definisce ER "estese") e ER obsolete
(approssimativamente quelle di
ed(1); ER di "base" in
POSIX.2). Le ER obsolete esistono per compatibilità con alcuni vecchi
programmi, e verranno discusse alla fine. POSIX.2 lascia aperti alcuni aspetti
della sintassi e della semantica delle ER: "(!)" denota scelte che
potrebbero non essere completamente portabili ad altre implementazioni di
POSIX.2.
Una ER (moderna) è una(!) diramazione o più diramazioni non
vuote*†,
diramazioni, separati da '|'. L'ER corrisponde a
qualsiasi cosa che corrisponda ad una delle diramazioni.
Una diramazione è formata da uno(!) o più
pezzi
concatenati. Corrisponde ad una corrispondenza per il primo pezzo, seguita da
una corrispondenza per il secondo, e così via.
Un pezzo è formato da un
atomo, eventualmente seguito da un
singolo(!) '*', '+', '?' o
limite. Un atomo seguito da '*' corrisponde
ad una successione di 0 o più corrispondenze dell'atomo. Un atomo
seguito da '+' corrisponde ad una successione di 1 o più corrispondenze
dell'atomo. Un atomo seguito da '?' corrisponde ad una successione di 0 o 1
corrispondenza dell'atomo.
Un
limite (o quantificatore) è formato da '{' seguito da un intero
decimale senza segno, eventualmente seguito da ',' eventualmente seguito da un
altro intero decimale senza segno, obbligatoriamente seguito da '}'. Gli
interi devono essere compresi fra 0 e
RE_DUP_MAX (255(!)) inclusi, e se
ce ne sono due, il primo non deve essere maggiore del secondo. Un atomo
seguito da un limite contenente un intero
i e nessuna virgola
corrisponde ad una successione di esattamente
i corrispondenze
dell'atomo. Un atomo seguito da un limite contenente un intero
i e una
virgola corrisponde ad una successione di
i o più corrispondenze
dell'atomo. Un atomo seguito da un limite contenente due interi
i e
j corrisponde ad una successione di
i fino a
j (inclusi)
corrispondenze dell'atomo.
Un atomo è formato da un'espressione regolare racchiusa fra "
()" (corrispondente ad una corrispondenza per l'espressione
regolare), un insieme vuoto di "
()" (corrispondente alla
stringa nulla)(!), un'
espressione parentetica (vedi sotto), '.'
(corrispondente ad un qualsiasi carattere singolo), '^' (corrispondente alla
stringa nulla a inizio riga), '$' (corrispondente alla stringa nulla a fine
riga), una '\' seguita da uno dei caratteri "
^.[$()|*+?{\"" (corrispondente a quel carattere interpretato
come un carattere normale), una '\' seguita da un qualsiasi altro carattere(!)
(corrispondente a quel carattere interpretato come un carattere normale, come
se la '\' non fosse presente(!)), oppure un singolo carattere privo di
ulteriori significati (interpretato come se stesso). Una '{' seguita da un
carattere che non sia una cifra è un carattere normale, non l'inizio di
un limite(!). È vietato terminare un'ER con '\'.
Un'
espressione parentetica è un elenco di caratteri racchiusi da
"
[]". Corrisponde di norma ad un qualsiasi singolo carattere
fra quelli della lista (ma vedi oltre). Se l'elenco inizia con '^',
l'espressione corrisponde ad un qualsiasi singolo carattere
non fra
quelli della lista (ma vedi oltre). Due caratteri nell'elenco separati da un
'-' formano un'abbreviazione per l'intera
serie di caratteri compresi
nella sequenza di collazione fra i due caratteri (inclusi). Per esempio,
"
[0-9]" corrisponde, in ASCII, ad una qualsiasi cifra
decimale. Due serie non possono(!) condividere un estremo, per esempio "
a-c-e". Le serie dipendono particolarmente dalla sequenza di
collazione, e un programma, per essere portabile, non dovrebbe dipenderne.
Se si vuole includere una ']' nell'elenco, bisogna metterla al primo posto (dopo
un eventuale '^'). Se si vuole includere un '-' nell'elenco, bisogna metterlo
al primo o all'ultimo posto, o come estremo destro di una serie. Se si vuole
usare un '-' come estremo sinistro di una serie, bisogna trasformarlo in un
elemento di collazione racchiudendolo fra "
[." e
"
.]" (vedi sotto). Eccetto queste combinazioni, e alcune
altre con '[' (vedi il prossimo paragrafo), tutti gli altri caratteri
speciali, inclusa la '\' perdono il loro significato speciale quando
all'interno di un'espressione parentetica.
All'interno di un'espressione parentetica, un elemento di collazione (un
carattere o una sequenza di più caratteri che viene ordinata come se
fosse un carattere singolo o una sequenza di collazione che sta per uno dei
due) racchiuso fra "
[." e "
.]" rappresenta
la sequenza di caratteri dell'elemento di collazione. La sequenza è un
unico argomento dell'elenco nell'espressione parentetica. Pertanto,
un'espressione che contiene un elemento di collazione a più caratteri
può corrispondere a più di un carattere. Per esempio, se la
sequenza di collazione include l'elemento di collazione "ch", allora
l'ER "
[[.ch.]]*c" corrisponde ai primi cinque caratteri di
"chchcc".
All'interno di un'espressione parentetica, un elemento di collazione racchiuso
fra "
[=" e "
=]" è una classe di
equivalenza, cioè la sequenza di caratteri di tutti gli elementi di
collazione equivalenti, lui incluso (se non ci sono altri elementi di
collazione equivalenti, il risultato è lo stesso che ci sarebbe se i
segni di delimitazione fossero "
[." e
"
.]"). Per esempio, se o e ô appartengono ad una
classe di equivalenza, allora `
[[=o=]]', `
[[=ô=]]' e
`
[oô]' sono tutti sinonimi. Una classe di equivalenza non
può essere un estremo di una serie.
All'interno di un'espressione parentetica, il nome di una
classe di
caratteri racchiusa fra "
[:" e "
:]"
rappresenta l'elenco di tutti i caratteri di quella classe. I nomi delle
classi standard di caratteri sono:
alnum |
digit |
punct |
alpha |
graph |
space |
blank |
lower |
upper |
cntrl |
print |
xdigit |
Questi rappresentano le classi di carattere definite in
wctype(3). Una
localizzazione potrebbe fornirne altre. Una classe di caratteri non può
essere usata come estremo di una serie.
Nel caso che un'ER possa corrispondere a più di una sotto-stringa di una
data stringa, l'ER corrisponde a quella che inizia per prima nella stringa. Se
l'ER può corrispondere a più sotto-stringhe che iniziano nello
stesso punto, l'ER corrisponde a quella più lunga. Le sottoespressioni
corrispondono anche alle sottostringhe più lunghe possibile, a patto
che l'intera corrispondenza sia la più lunga possibile, con le
sottoespressioni che iniziano prima nell'ER hanno priorità su quelle
che iniziano dopo. Si noti che in particolare, le sottoespressioni ad alto
livello hanno la precedenza sulle loro espressioni componenti, che sono di
livello più basso.
La lunghezza di una corrispondenza è misurata in caratteri, non in
elementi di collazione. Una stringa nulla è considerata più
lunga di una corrispondenza mancata. Per esempio, "
bb*"
corrisponde ai tre caratteri di mezzo di "abbbc", "
(wee|week)(knights|nights)" corrisponde a tutti e dieci i
caratteri di "weeknights", se "
(.*).*" è
corrisposto a "abc" la sottoespressione fra parentesi corrisponde ai
tre caratteri, e se "
(a*)*" è corrisposto a
"bc" sia l'intera ER che l'espressione tra parentesi corrispondono
alla stringa nulla.
Se viene richiesta una corrispondenza indipendente da maiuscole e minuscole,
l'effetto è essenzialmente lo stesso che si avrebbe togliendo ogni
differenza fra maiuscole e minuscole nell'alfabeto. Quando un carattere
alfabetico che esiste sia come maiuscola che come minuscola appare come
carattere ordinario al di fuori di un'espressione parentetica, viene, in
pratica, trasformato nell'espressione parentetica comprendente entrambi i
casi: per esempio, 'x' diventa "
[xX]". Quando un simile
carattere appare all'interno di un'espressione parentetica, la controparte
viene aggiunta all'espressione: ad esempio, "
[x]" diventa
"
[xX]" e "
[^x]" diventa
"
[^xX]".
Non viene imposto nessun limite particolare alla lunghezza delle ER(!). I
programmi, per essere portabili, non dovrebbero impiegare ER più lunghe
di 256 byte, in quanto un'implementazione potrebbe rifiutare una simile ER e
rimanere conforme a POSIX.
Le espressioni regolari obsolete si differenziano in diversi modi. '| ', '+', e
'?' sono caratteri ordinari e non hanno nessun equivalente per le loro
funzionalità. I delimitatori dei limiti sono "
\{" e
"
\}", mentre '{' e '}' sono caratteri ordinari. Le parentesi
delle sottoespressioni annidate sono "
\(" e "
\)", mentre '(' e ')' sono caratteri ordinari. '^' è un
carattere normale tranne che all'inizio dell'ER o(!) all'inizio di
un'espressione parentetica, '$' è un carattere normale tranne che alla
fine dell'ER o(!) alla fine di un'espressione parentetica, e and '*' è
un carattere normale se appare all'inizio dell'ER o all'inizio di
un'espressione parentetica (eventualmente preceduto da un '^') iniziale).
Infine, c'è un nuovo tipo di atomo, una
referenza all'indietro:
'\' seguita da una cifra decimale
d diversa da zero corrisponde alla
stessa sequenza di caratteri a cui corrisponde la
d-esima espressione
parentetica (contando, da sinistra verso destra, le sottoespressioni in base
alla posizione della loro parentesi di destra), in modo che, ad esempio,
"
\([bc]\)\1" corrisponda a "bb" o "cc"
ma non a "bc".
Avere due tipi di ER è un pasticcio.
Le specifiche attuali in POSIX.2 dicono che ')' è un carattere normale in
mancanza di un corrispondente '(': questo è un risultato non voluto di
una scelta sbagliata di vocaboli, e sarebbe meglio cambiarlo. Non fare
affidamento su questo.
Le referenze all'indietro sono un casino incredibile, e rendono molto difficile
un'implementazione efficiente. La loro definizione è pure ambigua:
"
a\(\(b\)*\2\)*d" corrisponde a "abbbd" o no?
È meglio non usarle.
Le specifiche in POSIX.2 sulle corrispondenze indipendenti da
maiuscole/minuscole sono approssimative. La definizione data sopra di
«un caso implica tutti i casi» è quella al momento
considerata corretta dagli implementatori.
Questa pagina è tratta dal pacchetto sulle espressioni regolari di Henry
Spencer.
grep(1),
regex(3)
POSIX.2, sezione 2.8 (Notazione per le espressioni regolari).
La traduzione italiana di questa pagina di manuale è stata creata da
Ottavio G. Rizzo <
[email protected]>, Giulio Daprelà
<
[email protected]>, Elisabetta Galli <
[email protected]> e Marco Curreli
<
[email protected]>
Questa traduzione è documentazione libera; leggere la
GNU
General Public License Versione 3 o successiva per le condizioni di
copyright. Non ci assumiamo alcuna responsabilità.
Per segnalare errori nella traduzione di questa pagina di manuale inviare un
messaggio a
[email protected]