Guida italiana all'uso del Perl-compatible regular expression


Versione 0.2 del 19 aprile 2000

Curatore: eaglestorm@iname.com (EagleStorm)

Ringraziamenti per i preziosi contributi:

Carlo Fusco

Autori aventi pubblicazioni tradotte all'interno della guida

Philip Hazel <ph10@cam.ac.uk>
Carl Franklin e Gary Wisniewski

inoltre voglio anche ringraziare tutte quelle persone che, pur avendo
contribuito con importanti suggerimenti e correzioni alla stesura del
presente documento, hanno manifestato il desiderio di rimanere anonimi.

Distribuzione:

Usenet: posting periodico su it.faq e it.comp.software.newsreader

web: http://www.geocities.com/fashionavenue/1075/pcre.txt

Licenza d'uso ed altre avvertenze:

Questo documento viene rilasciato secondo la licenza GNU General Public
License (GPL o copyleft) versione 2 della Free Software Foundation.
Chiunque è autorizzato a distribuire copie elettroniche o cartacee del
presente documento, allegarlo a raccolte, CD-ROM o programmi, a patto di
citare la fonte da cui è stato tratto. Inoltre il presente documento può
essere liberamente modificato in ogni sua parte purché venga rilasciato
secondo la medesima licenza e i nomi dei curatori della presente
versione vengano rimossi. L'autore non si assume _NESSUNA_
responsabilità per eventuali errori o inesattezze. ATTENZIONE: la
maggior parte di questo documento fa riferimento a traduzioni semi
integrali di quanto già pubblicato in lingua anglosassone sul
Perl-Compatible Language Expression. Questa guida è stata realizzata per
puro spirito volontaristico e senza alcun intento economico.

History:

V 0.1: Guida italiana all'uso del Perl-compatible regular expression

Indice degli argomenti:

-Prefazione
-Cosa bisogna sapere prima di leggere questo documento

Sezione 1: Il PCRE-style regular expression

1.1 A cosa serve il PCRE-style regular expression?
1.2 Cos'è il PCRE-style regular expression?
1.3 I metacaratteri
1.4 Meta-carattere "\" (backslash)
1.5 Meta-caratteri "^" e "$". Accento circonflesso e dollaro.
1.6 Meta-carattere "[" ("]"). Le classi di carattere.
1.7 Meta-carattere "|". Le alternative.
1.8 Modalità interne al PCRE (internal option setting).
1.9 I sotto modelli (subpattern)
1.10 Le ripetizioni
1.11 Back Reference
1.12 Le asserzioni
1.13 Subpattern per una volta sola (once-only)
1.14 Subpattern condizionate
1.15 Commenti
1.16 Credits

Sezione 2: Espressioni regolari - Perl Regular Expression Tutorial

2.1 Introduzione al tutorial PCRE
2.2 Semplici esempi di espressioni regolari
2.3 Metacaratteri
2.4 Caratteri riservati
2.5 Cose da ricordare


Prefazione
----------

Questo documento ha l'ambizione di colmare almeno parzialmente la
l'assenza di informazioni in lingua italiana disponibili in rete
sulla funzionamento del Perl-Compatible Language Expression.


Cosa bisogna sapere prima di leggere questo documento
-----------------------------------------------------

Questa guida si pone come complemento per una conoscenza approfondita di
tutti i prodotti software che impiegano espressioni regolari per
effettuare ricerche. Il modo in cui il p-cre è stato implementato
all'interno di questi prodotti esula dagli obiettivi qui definiti. E' da
considerarsi quindi buona norma, prima di affrontare questa guida,
comprendere in dettaglio come possano essere introdotte le espressioni
regolari al loro interno.


Sezione 1: Il PCRE-style regular expression

1.1 A cosa serve il PCRE-style regular expression?

Il PCRE-style regular expression estende notevolmente la potenza
delle tecniche di scoring di Hamster. In altri termini, offre la
possibilità di includere alternative e ripetizioni allargando o
restringendo l'intervallo di corrispondenza nel novero delle
stringhe o dei valori possibili.

Un semplice esempio concernente i filtri sulle repliche è già
stato illustrato al punto 7.7. Il modello {^Re:\s|^R:\s} è in
grado di filtrare tutte le stringhe che iniziano per "Re: " o per
"R: ". Questo modello non è in alcun modo riproducibile a meno di
non utilizzare interfacce complesse (es. alcuni motori di ricerca)
o potenti motori procedurali come il PCRE-style.

Senza PCRE-style, Hamster non sarebbe in grado di filtrare questo
tipo di contenuti. La stessa cosa è stata compresa da altri
sviluppatori che hanno adottato il PCRE-style nei loro software.
Tra questi programmi posso ricordare Pegasus-mail, The Bat!, Xnews
ed Agent.

1.2 Cos'è il PCRE-style regular expression?

La PCRE library è un set di funzioni che implementano espressioni
regolari con condizioni da soddisfare usando la stessa sintassi e
semantica del Perl 5 (con qualche piccola differenza).
L'implementazione corrente corrisponde al Perl 5.005.

Hamster fa uso del Philip Hazel's PCRE package. Questo punto è
una versione molto condensata della pagina originale sul PCRE. Non
appaiono le sezioni sulla programmazione dell'interfaccia e sulle
differenze tra il Perl regex e il PCRE.

Una espressione regolare è una condizione, o un modello di
condizioni, che deve essere soddisfatta da una stringa, partendo
da sinistra verso destra. La maggior parte dei caratteri valgono
di per sé in un modello, e misurano o soddisfano i corrispondenti
caratteri oggetto della nostra attenzione. Con un esempio
terra-terra, possiamo avere:

The quick brown fox

che misura una porzione di stringa che è identica a se stessa.

Il potere delle regular expression deriva dall'abilità di
includere alternative e ripetizioni nel modello. Queste sono
codificate nel modello attraverso l'uso di "meta-caratteri", i
quali non valgono di per sé, ma sono interpretati secondo modalità
particolari.

1.3 I metacaratteri

Ci sono due differenti set di meta-caratteri: quelli che sono
riconosciuti ovunque nel modello (ad eccezione di quando sostano
all'interno di parentesi quadre, ovvero di una classe) e quelli
che sono riconosciuti nelle parentesi quadre.

Al di fuori delle parentesi quadre, i meta-caratteri sono come
segue:

\ carattere generico "escape", con diversi usi
^ corrisponde l'inizio della stringa
(oppure di una riga, in modalità multiline)
$ corrisponde la fine della stringa
(oppure di una riga, in modalità multiline)
. misura ogni carattere ad eccezione delle nuove righe
(predefinito)
[ inizia una definizione di classe di un carattere
| inizia un ramo alternativo
( inizia un sub modello
) termina un sub modello
? estende il significato di (
anche 0 oppure 1 quantità
anche "quantifier minimizer"
* 0 or more quantifier
+ 1 oppure più quantità
{ inizia min/max quantità

La parte di un modello che si trova tra parentesi quadre viene
identificata come "classe di caratteri". In una classe di
caratteri gli unici meta-caratteri sono:

\ carattere generico "di fuga" (escape
] terminatore della classe

1.4 Meta-carattere "\" (backslash)

Ha diversi significati e funzioni. Per prima cosa se seguito da un
carattere non alfa-numerico, elimina ogni significato speciale che
il carattere può avere. Questo uso del backslash come carattere di
fuga è valido sia all'interno che all'esterno delle classi di
carattere "[...]"

Per esempio, se si vuole misurare il carattere "*", scriveremo
"\*" nel modello. Questa corrispondenza si verifica comunque,
anche nel caso in cui il carattere successivo non appartenga
all'elenco dei metacaratteri. Quindi qualsiasi carattere
non-alfanumerico preceduto da "\" misura se stesso. In
particolare, se si vuole proprio corrispondere un backslash,
scriveremo "\\".

Se un modello è compilato con l'opzione PCRE_EXTENDED, i caratteri
spazio " " nel modello (oltre che nelle classi di carattere) e
tutti i caratteri tra "#" e il carattere di riga successiva (#
serve infatti per inserire i commenti) saranno ignorati. In questo
caso, un backslash può essere impiegato se abbiamo l'esigenza di
includere un carattere spazio o un carattere # come parte del
modello.

Con Hamster, per corrispondere esattamente un subject di questo
tipo "#free pictures", ricorreremo a questo ScorePattern:

{^\#free\spictures$} dove:

^ corrisponde l'inizio stringa
\# corrisponde "#"
\s corrisponde un carattere di spazio (vi ricordate "^Re:\s"?)
$ corrisponde la fine della stringa

Un secondo uso del backslash sta nel codificare i caratteri non
visibili (printing a video) in un modo comprensibile. Non ci sono
restrizioni sulla sostituzione dei caratteri non visibili, a
eccezione dello zero binario (1 bit) che termina il modello.
Quando un modello viene preparato da un editor di testo, è
solitamente più facile usare un elemento della seguente sequenza
piuttosto che il rispettivo carattere binario:

\a carattere BEL (suono) (hex 07)
\cx "control-x", dove x è un carattere
\e escape (hex 1B)
\f formfeed (hex 0C)
\n nuova riga (hex 0A)
\r ritorno a capo (hex 0D)
\t tabulazione (hex 09)
\xhh carattere con codice esadecimale hh
\ddd carattere con codice ottale ddd, oppure backreference

Il preciso effetto di "\cx" è come segue: il sesto bit coincide
con lo spartiacque tra i primi 64 caratteri e quelli successivi
fino al settimo bit, ovvero 128. Il valore di x viene invertito in
modo semi-speculare e riportato nell'altra metà. Unica eccezione,
se "x" è una lettera minuscola viene convertita in maiuscola.
Così "\cz" diventerà (26) hex 1A (z ->Z ->5a ->90 90-64=26),
mentre "\c{" diventerà (59) hex 3b ({ ->{ ->7b ->123 123-64=59),
mentre "\c;" diventerà (123) hex 7b (; ->; ->3b ->59 59+64=123).

Dopo "\0" fino a due ulteriori cifre ottali possono essere lette.
In entrambi i casi, se ci sono meno di due cifre, saranno usate
solo quelle presenti. Così, la sequenza "\0\x\07" specifica due
zero binari seguiti da un carattere BEL. Assicuratevi di fornire
due cifre dopo lo zero iniziale se il carattere che segue fosse
anche esso una cifra ottale.

Il trattamento di un backslasch seguito da una cifra diversa da 0
è complicato. Al di fuori di una classe di caratteri, il PCRE lo
legge con le cifre successive come numero decimale. Se il numero è
inferiore a 10, o se ci sono almeno altrettanti parentesi (...)
nell'espressione, l'intera sequenza viene considerata come back
reference. Una descrizione di come questa lavori viene fornita nei
punti successivi, seguendo il filo conduttore della discussione
dei sub-modelli racchiusi nelle parentesi. Per il momento può
bastare questo esempio di subpattern con back reference:
"(\b\w+\b) to \1"

Dentro a una classe di caratteri, oppure se il numero decimale è
più grande di 9 e in precedenza non si riscontra un numero di
subpattern sufficiente a realizzare una back reference, il PCRE
rilegge fino a tre cifre ottali seguite da backslash, e genera un
byte singolo dagli ultimi significativi 8 bit (0-255) del valore
in poi. Ogni ulteriore cifra vale per se stessa. Per esempio:

\040 corrisponde a un altro modo di scrivere uno spazio
\40 è la stessa cosa, ammesso che non ci siano 40 precedenti
subpattern
\7 corrisponde sempre a una back reference
\11 potrebbe essere una back reference oppure un altro modo di
scrivere tab
\011 corrisponde sempre una tabulazione
\0113 corrisponde a una tabualazione seguita dal carattere "3"
\113 è il carattere con valore ottale 113 (dato anche che non ci
possono essere più di 99 back reference)
\377 è un byte che equivale a un bit
\81 è una back reference o uno zero binario seguito dai due
caratteri "8" e "1"

I valori ottali di 100 o più grandi non devono essere preceduti da
uno zero iniziale perché non vengono comunque lette più di tre
cifre.

Tutte le sequenze che definiscono un byte singolo possono essere
usate sia dentro che fuori le classi di carattere. In aggiunta,
dentro una classe di caratteri, la sequenza "\b" viene
interpretata come carattere backspace (spazio barra spaziatrice,
hex 08). Al di fuori di una classe di caratteri ha un significato
particolare (leggi oltre).

Il terzo uso del backslash è per specificare alcuni tipi di
caratteri generici:

\s ogni spazio bianco
\S ogni carattere che non è uno spazio bianco
\w parola formata solo da caratteri alfanumerici più "_"
\W il complemento a \w

Ogni coppia di queste quattro sequenze partiziona il set completo
dei caratteri in due set distinti. Ogni dato carattere ne
corrisponde uno, e solo uno, di ogni coppia.

\w corrisponde a ogni lettera o cifra più il carattere "_"
(underscore o sottolineatura), e cioè, ogni carattere che può fare
parte di una "parola" Perl. La definizione di lettere e cifre
viene controllata attraverso la tavola dei caratteri PCRE e,
potrebbe variare nel caso in cui una venisse applicata una
specifica tabella locale (leggi supporto locale, sopra). Per
esempio, in Francia (locale fr) o in Italia (locale it), alcuni
codici di carattere più grandi di 128 sono usati per le lettere
accentate, e questi sono corrisposti con \w.

Questi tipi di sequenze possono apparire sia dentro che al di
fuori di una classe di caratteri. Corrispondono unicamente un
carattere del tipo appropriato. Se il punto di corrispondenza
corrente è alla fine della stringa, il loro impiego fallirà dato
che non esistono caratteri da corrispondere.

Il quarto uso di un backslash è per alcuni tipi di semplici
asserzioni. Un asserzione specifica una condizione che deve essere
soddisfatta in un punto particolare della stringa, senza
corrispondere alcun carattere della stringa. L'uso di subpattern
per asserzioni più complicate è descritto più sotto.

Le asserzioni con backslash sono

\b confine o punto estremo (inizio/fine) di parola
\B non è un confine di parola
\A inizio della stringa (indipendente alla modalità
multiriga)
\Z fine della stringa o della nuova riga (indipendente dalla
modalità multiriga)
\z fine della stringa (indipendente dalla modalità multiriga)

Queste asserzioni non possono apparire in una classe di caratteri
(ma osserva che "\b" ha un significato differente, letteralmente
il carattere backspace, come abbiamo visto in precedenza, dentro a
una classe di caratteri).

Un confine di parola corrisponde alla posizione nella stringa dove
il carattere corrente e quello precedente non corrispondono
rispettivamente né \w, né \W (altrimenti uno corrisponderebbe \w,
mentre l'altro \W), oppure l'inizio o la fine di una stringa se il
primo o l'ultimo carattere corrisponde \w, rispettivamente.

Le asserzioni \A, \Z, e \z differiscono dai tradizionali "^" e "$"
(descritti sotto) nel fatto che essi corrispondono all'inizio vero
e proprio, e alla fine, della stringa, qualsiasi modalità PCRE
venga impostata. xxx

1.5 Meta-caratteri "^" e "$". Accento circonflesso e dollaro.

Al di fuori di una classe di caratteri, nella modalità di
corrispondenza predefinita, il carattere "^" (accento
circonflesso) è un'asserzione che è vera solo se il punto di
corrispondenza corrente è all'inizio della stringa. Dentro una
classe di caratteri, "^" ha un significato completamente diverso
(leggi sotto).

L'accento circonflesso non ha bisogno di essere il primo carattere
del modello se viene implicato un numero di alternative, ma
dovrebbe essere il primo elemento in ogni alternativa in cui
appare, ammesso che il modello debba corrispondere quel ramo. Se
tutte le possibili alternative cominciano con un accento
circonflesso, ovvero se il modello è obbligato a corrispondere
solo all'inizio della stringa, si ha un modello ancorato.
(Esistono altri tipi di costruzione che possono ancorare un
modello).

Il carattere "$" (dollaro) è un'asserzione vera solo se il punto
di corrispondenza corrente si trova alla fine della stringa, o
immediatamente prima di un carattere di nuova riga che è l'ultimo
carattere del modello nella stringa (predefinito). Il dollaro non
ha bisogno di essere l'ultimo carattere del modello se viene
implicato un numero di alternative, ma dovrebbe essere l'unico
elemento in un ogni ramo in cui appare. Il dollaro non ha un
significato speciale in una classe di caratteri.

Il significato del dollaro può essere cambiato in modo da
corrispondere solo la fine esatta della stringa (niente più "$"
nelle alternative) impostando l'opzione PCRE_DOLLAR_ENDONLY al
momento compilazione o della verifica della corrispondenza. Questo
non influenza l'asserzione \Z.

Il significato di "^" e di "$" cambia se viene impostata l'opzione
PCRE_MULTILINE (modalità multiriga). In questo caso, essi
rispettivamente corrispondono immediatamente dopo e immediatamente
prima un asserzione interna "\n", oltre alla corrispondenza alla
fine e all'inizio della stringa. Per esempio, il modello /^abc$/
corrisponde la stringa "dev\nabc" in modalità multiriga, ma non
diversamente (ovviamente "\n" nella stringa equivale alla nuova
riga). Conseguentemente i modelli che risultano ancorati in
modalità monoriga avendo tutti i rami che cominciano con "^" non
sono più ancorati in modalità multiriga. Attenzione: l'opzione
PCRE_DOLLAR_ENDONLY viene ignorata se viene impostata quella
PCRE_MULTILINE.

Osservate come le sequenze \A, \Z, e \z possano essere impiegate
per corrispondere l'inizio o la fine della stringa in entrambe le
modalità. Se tutti i rami del modello cominciano con \A, esso è
sempre ancorato, sia che la modalità PCRE_MULTILINE sia attivata o
che non lo sia. Al di fuori di una classe di caratteri, un punto
nel modello corrisponde ogni singolo carattere della stringa,
compresi quelli non visibili (printing a video), tranne
(predefinito) quello di nuova riga ("\n"). Se viene impostata
l'opzione PCRE_DOTALL, i punti corrispondono anche le nuove righe.
Il trattamento di un punto è completamente indipendente dal
trattamento dei caratteri "^" e "$", con la sola relazione che
sono entrambi possono concernere caratteri di nuova riga. Il punto
non ha significati particolari in una classe di caratteri.

1.6 Meta-carattere "[" ("]"). Le classi di carattere.

Un parentesi quadra di apertura introduce una classe di caratteri,
terminata da una successiva parentesi quadra di chiusura. Una
parentesi quadra chiusa, in sé, non ha un significato particolare.
Se si richiede una parentesi quadra chiusa come membro della
classe, deve essere il primo carattere nella classe (dopo un
accento circonflesso, se presente) o sottratta con uno backslash.

Una classe di caratteri corrisponde un singolo carattere nella
stringa; il carattere deve essere nel set dei caratteri definiti
dalla classe, a meno che il primo carattere nella classe non sia
un accento circonflesso "^", nel qual caso il carattere della
stringa non deve essere nel set definito dalla classe. Se "^" è
realmente necessario come membro della classe, assicurate che non
sia il primo carattere, o trattenetelo con un backslash

Per esempio, la classe [aeiou] corrisponde ogni vocale minuscola,
mentre [^aeiou] corrisponde ogni carattere che non è vocale
minuscola. Osservate come l'accento circonflesso "^" sia solo una
scorciatoia per specificare quali caratteri sono ammessi dalla
classe attraverso la definizione di quelli che non lo sono. Non si
tratta di asserzione: la classe occupa solo un carattere della
stringa, ma fallisce se il punto corrente di corrispondenza si
trova alla fine della stringa.

Quando è attiva la modalità CASELESS (default di Hamster), tutte
le lettere in una classe rappresentano sia la loro versione
maiuscola che quella minuscola, così, per esempio, una classe
caseless [aeiou] corrisponde "A" al pari di "a", mentre una classe
caseless [^aeiou] non corrisponde "A" (in questo ultimo caso anche
con la modalità caseful).

Il carattere di nuova riga non è mai trattato in modo speciale
in classi di carattere, qualunque modalità venga adottata, sia
essa PCRE_DOTALL o PCRE_MULTILINE. Una classe come [^a]
corrisponderà sempre a una nuova riga.

Il carattere "-" può essere usato per specificare un range di
caratteri in una classe. Per esempio, [d-m] corrisponde ogni
lettera tra d e m, incluse. Se un carattere "-" è richiesto come
membro di una classe, deve essere trattenuto all'inizio o alla
fine della classe. Non è possibile avere il carattere "]" come
carattere finale di un range, dato che una sequenza come [w-]
viene interpretata come classe di due caratteri. La
rappresentazione ottale o esadecimale di "]" può, tuttavia, essere
usata per terminare un range.

I range operano in sequenza e nell'ordine ASCII. Possono anche
essere usati per caratteri specificati numericamente, per esempio
[\000-\037]. Se un range che include lettere viene usato quando è
impostata la modalità caseless, esso corrisponde le lettere in una
sorta di ordine continuo. Per esempio, [W-c] equivale a
[][\^_`wxyzabc], anch'essa in modalità caseless, e se la tabella
locale dei caratteri "it" è in uso, [\xc8-\xcb] corrisponde alle
"e" accentante in entrambi i casi.

Le sequenze \d, \D, \s, \S, \w e \W possono anche apparire
all'interno di una classe di caratteri, e aggiungere i caratteri
che essi corrispondono alla classe. Per esempio, [\dABCDEF]
corrisponde ogni cifra esadecimale. Un accento circonflesso può
essere impiegato con profitto con la versione maiuscola di queste
sequenze per specificare un più ristretto set di caratteri
rispetto a quello corrisposto dalla versione minuscola. Per
esempio, la classe [^\W_] corrisponde ogni lettera o cifra, ma non
il carattere di sottolineatura "_" (underscore).

Tutti i caratteri non alfanumerici all'infuori di \, -, ^
(all'inizio) e il finale ] non sono caratteri speciali nelle
classi di carattere, ma non causano alcun problema se sono
trattenuti con il backslash.

1.7 Meta-carattere "|". Le alternative.

Le barre verticali sono impiegate per separare modelli
alternativi, all'interno dello stesso modello.

Per esempio, il modello

gilbert|sullivan

corrisponde sia "gilbert" che "sullivan". Ogni tipo di alternativa
può apparire, compresa l'alternativa vuota (corrispondenza di una
stringa vuota). Il processo di verifica cerca ogni alternativa in
gioco, da sinistra a destra, e applica la prima che trova
riscontro. Se le alternative sono dentro un subpattern (definito
più sotto), riscontrare comporta corrispondere il resto del
modello principale così come le alternative presenti nel
subpattern.

1.8 Modalità interne al PCRE (internal option setting).

Le modalità PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL e
PCRE_EXTENDED possono essere modificate dall'interno del modello
attraverso una sequenza di lettere esclusive del PCRE racchiuse
tra "(?" e ")". Le lettere in oggetto sono:
m per PCRE_MULTILINE
s per PCRE_DOTALL
x per PCRE_EXTENDED

Per esempio, (?im) assegna le modalità caseless e multiline. E'
anche possibile offrire il loro complemento precedendo la lettera
con un carattere "-" oppure, offrire una combinazione di queste
modalità attivandone ora la loro funzione originale, ora il loro
complemento, come in (?im-sx), che imposta PCRE_CASELESS and
PCRE_MULTILINE mentre annulla PCRE_DOTALL e PCRE_EXTENDED. Se una
lettera appare sia prima che dopo il carattere "-", la modalità
viene disabilitata.

Lo scopo di queste opzioni di modifica si comprende quando occorre
il cambiamento di modalità in una parte del modello. Per le
modalità che sono al di fuori di ogni subpattern (definito più
sotto), l'effetto è lo stesso se la modalità viene attivata (o
disattivata) all'inizio del modello principale.

I modelli successivi si comportano esattamente tutti allo stesso
modo:

(?i)abc
a(?i)bc
ab(?i)c
abc(?i)

Tutti equivalgono a compilare il modello abc con la modalità
PCRE_CASELESS attiva. In altre parole, i cambiamenti ad alto
livello delle modalità si applicano all'intero modello (a meno che
non ci siano altri cambiamenti all'interno delle subpattern). Se
ci sono più cambiamenti di modalità a livello di pattern
principale, sarà impiegato quello più a destra.

Se serve un'opzione di modifica all'interno di un subpattern,
l'effetto è differente. Questo è un cambiamento di modalità in in
Perl 5.005. Un opzione cambia all'interno di un subpattern e
influenza solo quella parte di subpattern che la segue, così:

(a(?i)b)c

corrisponderà abc e aBc, ma non altre stringhe (assumendo che non
sia usata la modalità PCRE_CASELESS). Da questo si desume che le
opzioni possono causare differenti cambiamenti di modalità in
differenti parti del modello. Ogni cambiamento fatto in una
alternativa viene applicato al ramo successivo all'interno dello
stesso subpattern. Per esempio:

(a(?i)b|c)

corrisponde "ab", "aB", "c" e "C", anche se nel riscontro di "C"
il cambiamento di modalità è avvenuto nel primo ramo. Questo
accade perché l'effetto della modifica di un'opzione avviene a
livello di compilazione. Altrimenti, si verificherebbero alcuni
comportamenti piuttosto bizzarri.

Una particolarità su X. La modalità (?X) è speciale perché deve
sempre anticipare nel modello tutte le caratteristiche addizionali
che dovrebbe influenzare, anche quando si trova al livello di
pattern principale. E' quindi consigliabile collocarla all'inizio.

1.9 I sotto modelli (subpattern).

I subpattern sono delimitati da parentesi (tonde), e possono
essere nidificati. Inserire parte di un modello come subpattern ha
due effetti:

1. Localizza un set di alternative. Per esempio, il modello:

cat(aract|erpillar|)

corrisponde a una delle parole "cat", "cataract" oppure
"caterpillar". Senza le parentesi, corrisponderebbe "cataract",
"erpillar" oppure una stringa vuota.

2. Pianifica il subpattern come subpattern di cattura (come
definito sopra). When the whole pattern matches, that portion of
the subject string that matched the subpattern is passed back
to the caller via the ovector argument of pcre_exec(). xxx
Le parentesi aperte sono contate da sinitra a destra (partendo da
1) per ottenere il numero delle subpattern di cattura.

Per esempio, se la stringa "the red king" viene affrontata dal
modello:

the ((red|white) (king|queen))

le substringhe catturate sono "red king", "red", and "king" e sono
numerate 1, 2, and 3.

Il fatto che le parentesi realizzino due funzioni non è sempre di
aiuto. In alcuni casi il raggruppamento dei subpattern è richiesto
senza la caratteristica della cattura. se una parentesi aperta è
seguita da "?:", il subpattern non sarà definito "di cattura", e
non ne sarà tenuto conto nel computo del numero delle subpattern
di cattura successive. Per esempio, se la stringa "the white
queen" è affrontata dal modello:

the ((?:red|white) (king|queen))

le substringhe catturate sono "white queen" e "queen" e sono
numerate 1 e 2. The maximum number of captured substrings is 99,
and the maximum number of all subpatterns, required at the start
of a non-capturing subpattern, the option letters may appear
between the "?" and the ":".xxx
Così i due modelli:

(?i:saturday|sunday)
(?:(?i)saturday|sunday)

corrispondono esattamente lo stesso set di stringhe. Poiché i rami
alternativi sono testati da sinistra verso destra e le opzioni di
modalità non sono reimpostate prima della fine del subpattern, il
cambiamento di modalità in un ramo influenzerà i rami subseguenti.
In tal modo il modello sopra corrisponderà "SUNDAY" così come
"Saturday".

1.10 Le ripetizioni

La ripetizione è specificata da quantificatori, i quali possono
seguire ognuno dei seguenti articoli:

un carattere singolo, possibilmente il metacarattere
una classe di caratteri
una back reference (trattate al punto successivo)
un subpattern tra parentesi (a meno che non sia un'asserzione,
illustrate più avanti)

Il quantificatore specifica un minimo e un massimo numero di
corrispondenze permesse, assegnando i due valori in parentesi
graffe, separate da una virgola. Questi valori devono essere
inferiori a 65536, e il primo deve essere inferiore o uguale al
secondo. Per esempio:

z{2,4}

corrisponde "zz", "zzz", or "zzzz". Una parentesi graffa di
chiusura per conto suo non rappresenta un carattere speciale. Se
il secondo valore viene omesso, ma la virgola è presente, non c'è
alcun limite superiore; se il secondo valore e la virgola sono
entrambi omessi, il quantificatore specifica un numero esatto di
corrispondenze richieste.
Così:

[aeiou]{3,}

corrisponde almeno 3 successive vocali, ma può corrisponderne
molte di più, mentre

\d{8}

corrisponde esattamente 8 cifre. Una parentesi graffa aperta che
appare in una posizione dove un quantificatore non è permesso, o
uno che non corrisponde la sintassi di un quantificatore, è
considerato come carattere letterale. Per esempio, {,6} non è un
quantificatore, ma una stringa letterale di quattro caratteri.

Il quantificatore {0} è permesso e determina una reazione
dell'espressione come se il precedente articolo e il
quantificatore non fossero presenti.

Per convenienza, (e compatibilità all'indietro) i tre più comuni
quantificatori hanno specifiche abbreviazioni:

* equivale a {0,}
+ equivale a {1,}
? equivale a {0,1}

E' possibile costruire cicli infiniti seguendo un subpattern che
non corrisponde alcun carattere con un quantificatore che non
prevede limiti superiori, per esempio:

(a?)*

Le versioni più recenti di Perl e PCRE forniscono un errore
all'atto della compilazione per alcuni modelli. Tuttavia, poiché
ci sono casi dove questa possibilità potrebbe rivelarsi utile,
tali modelli sono già stati accolti, ma se qualsiasi ripetizione
del subpattern non dovesse corrispondere ad alcun carattere, il
ciclo si spezzerebbe per forza.

I quantificatori sono avidi di risorse per eccellenza, in altre
parole, essi corrispondono il più possibile (fino al massimo
numero di volte possibili), senza causare l'arresto del modello
per fallimento. L'esempio classico di dove questo crea problemi è
nel tentativo di corrispondere commenti nel sorgente C. Questi
appaiono tra le sequenze /* e */ e dentro una singola sequenza
possono comparire i caratteri * e /. Un tentativo di corrispondere
i commenti in C si ha comparando il modello:

/\*.*\*/

con la stringa

/* first command */ not comment /* second comment */

ma fallirà poiché corrisponde l'intera stringa a causa
dell'avidità dell'elemento .* .

Tuttavia, se un quantificatore è seguito da un punto
interrogativo, allora cesserà di essere avido e invece
corrisponderà il minimo numero di volte possibili, così il
modello:

/\*.*?\*/

farà la cosa giusta con un commento C. Il significato dei vari
quantificatori non è cambiato, ma solo il numero preferibile di
corrispondenze. Non confondete questo uso delle doppie, come in:

\d??\d

che di preferenza corrisponde una sola cifra, ma può anche
corrisponderne due se quello è l'unico modo perché il resto del
modello corrisponda.
which matches one digit by preference, but can match two if that
is the only way the rest of the pattern matches.xxx

Se si attivasse la modalità PCRE_UNGREEDY (comunque non
disponibile su Perl) allora i quantificatori non sarebbero avidi
per definizione, ma individualmente uno potrebbe essere reso avido
facendolo seguire da un punto interrogativo. In altre parole, esso
inverte la condotta predefinita.

Quando un subpattern viene quantificata con un valore minimo più
grande di 1 o con un limitato valore massimo, sarà richiesto tanto
più spazio per il modello compilato in proporzione alla dimensione
dei valori minimi e massimi.

Se un modello parte .* con allora sarà implicitamente ancorato,
dato che qualsiasi cosa segua sarà processata su ogni posizione
della stringa. PCRE tratta questa stringa come se fosse preceduta
da \A.

Quando una subpattern di cattura è ripetuta, il valore catturato è
la sottostringa che corrisponde la ripetizione finale.
Per esempio, dopo:

(tweedle[dume]{3}\s*)+

con la stringa "tweedledum tweedledee" il valore della substringa
catturata sarà "tweedledee". Tuttavia, se ci fossero subpattern
nidificate, il valore corrispondente catturato potrebbe essere
impostato.
Per esempio, dopo:

/(a|(b))+/

con la stringa "aba" il valore della seconda substringa catturata
è "b".

1.11 Back Reference

Al di fuori di una classe di caratteri, un backslash seguito da
una cifra più grande di 0 (anche molto più grande) è una back
reference che serve a catturare subpattern vicine (ovvero alla sua
sinistra) nel modello, a condizione che ci siano sufficienti (...)
parentesi di cattura precedenti.

Tuttavia, se il numero decimale che segue il backslash è inferiore
a 10, è sempre considerato come back reference, e causa un errore
solo se non ci sono altrettante parentesi di cattura alla sua
sinistra, per un numero pari quindi a quello riportato dopo il
backslash inferiore a 10. Leggete il punto riservato al backslash
più sopra per avere ulteriori dettagli sul trattamento delle cifre
seguite da un backslash.

Una back reference corrisponde qualsiasi cosa corrisposta dal
subpattern di cattura nella stringa corrente, piuttosto che
qualsiasi cosa che corrisponde lo stesso subpattern. Così il
modello

(sens|respons)e and \1ibility

corrisponde "sense and sensibility" e "response and
responsibility", ma non "sense and responsibility". Se è attiva la
modalità caseful durante il funzionamento della back reference,
allora la "dimensione" della lettera diviene rilevante. Per
esempio,

((?i)rah)\s+\1

corrisponde "rah rah" e "RAH RAH", ma non "RAH rah", anche se il
subpattern originale di cattura viene corrisposto in modalità
caseless.

Ci può essere più di una back reference verso lo stesso
subpattern. Se un subpattern non è stato ancora usato in una
particolare corrispondenza, allora ogni back reference verso di
esso fallirà comunque. Per esempio, il modello

(a|(bc))\2

fallisce sempre se parte per corrispondere "a" piuttosto di "bc".
Poiché ci può essere un massimo di 99 back reference, tutte le
cifre che seguono il backslash sono considerate come potenziali
numeri per back reference. Se il modello continua proprio con un
carattere cifra, allora si deve usare un delimitatore per
terminare la back reference. Se è attiva la modalità PCRE_EXTENDED
questo può essere costituito da uno spazio bianco. Altrimenti, si
può usare anche un commento vuoto.

Una back reference che si trova dentro le parentesi alle quali si
riferisce fallisce quando il subpatter è usato per la prima volta,
così, per esempio, (a\1) non corrisponderà mai. Tuttavia, tali
reference possono essere utili all'interno di subpattern ripetute.
Per esempio il modello

(a|b\1)+

corrisponde ogni numero di "a" e anche "aba", "ababaa", ecc. A
ogni ripetizione del subpattern, la back reference corrisponde la
stringa di caratteri corrispondente alla precedente ripetizione.
Perché questa funzioni, il modello deve essere tale da non imporre
alla prima ripetizione di aver bisogno di corrispondere la back
reference. Questo può essere realizzato usando l'avvicendamento,
come nell'esempio precedente o usando un quantificatore con un
minimo pari a zero.

1.12 Le asserzioni

Un'asserzione è un test sui caratteri seguenti o precedenti il
punto di corrispondenza corrente senza in realtà misurare alcun
carattere. Le semplici asserzioni codificate come \b, \B, \A, \Z,
\z, ^ e $ sono state descritte nei punti precedenti. Le asserzioni
più complesse sono codificate come subpattern. Ce ne sono di due
tipi: quelle che guardano avanti (lookahead) rispetto alla
posizione corrente nella stringa, e quelle che guardano indietro
(look behind).

Un asserzione subpattern è normalmente corrisposta, ad eccezione
di quando non richiede di cambiare il punto di corrispondenza
corrente. Le asserzioni (lookahead) cominciano con (?= per quelle
positive e con (?! per quelle negative.
Per esempio,

\w+(?=;)

corrisponde una parola seguita da un punto e virgola, ma non
comprende il punto e virgola nella corrispondenza, e

foo(?!bar)

corrisponde ogni ricorrenza di "foo" non seguita da "bar".
Osservate questo modello apparentemente simile:

(?!foo)bar

non trova la ricorrenza di "bar" preceduta da qualcosa di diverso
da "foo"; trova qualsiasi ricorrenza di "bar", non importa quale,
poiché l'asserzione (?!foo) è sempre vera quando i tre caratteri
vicini sono "bar". Un'asserzione lookbehind deve realizzare questo
scopo.

Le asserzioni lookbehind cominciano con (?<= per quelle positive
e con (?<! per quelle negative. Per esempio,

(?<!foo)bar

trova ogni ricorrenza di "bar" non preceduta da "foo". I contenuti
di un'asserzione lookbehing sono ristretti in modo che tutte le
stringhe che corrisponde debbano avere una lunghezza fissa.
Tuttavia, se ci sono diverse alternative, non devono avere tutti
la stessa lunghezza fissa. Così:

(?<=bullock|donkey)

è permesso, ma

(?<!dogs?|cats?)

è causa di un errore all'atto della compilazione. I rami che
corrispondono due differenti lunghezze delle stringhe sono
permessi solo nel pattern principale di un'asserzione lookbehind.
Questa è un'estensione confrontata con il Perl 5.005, che richiede
che tutti i rami corrispondano la stessa lunghezza della stringa.
Un asserzione come:

(?<=ab(c|de))

non è permessa, poiché il suo unico ramo (alternativa) può
corrispondere due differenti lunghezze, ma diventa accettabile se
riscritta per usare due rami:

(?<=abc|abde)

L'implementazione delle asserzioni lookbehind serve, per ogni
alternativa, a spostare temporaneamente la posizione corrente
all'indietro per una certa larghezza fissa e, quindi, a cercare
una corrispondenza. Se non ci sono caratteri sufficienti prima
della posizione corrente, il processo fallisce.

Le asserzioni possono essere nidificate in ogni combinazione. Per
esempio,

(?<=(?<!foo)bar)baz

corrisponde una ricorrenza di "baz" preceduta da "bar" che non è
preceduta da "foo".

Le asserzioni subpattern non sono subpattern di cattura e non
possono essere ripetute, poiché sarebbe senza senso asserire la
stessa cosa diverse volte. Se un'asserzione contiene subpattern di
cattura dentro di essa, queste sono sempre contate allo scopo di
numerare le subpattern di cattura nell'intero modello. Le
substringhe catturate saranno impiegate per le asserzioni
positive, ma non avranno senso alcuno per quelle negative.

Le asserzioni contano fino a un massimo di 200 subpattern in
parentesi.

1.13 Subpattern per una volta sola (once-only)

Sia con i valori massimi e minimi di ripetizione, il fallimento di
ciò che segue normalmente determina la rivalutazione della voce
ripetuta per vedere se un numero differente di repliche permette
al resto del modello di trovare una ricorrenza. A volte, è utile
prevenire questo, sia per cambiare la natura della ricerca, sia
per causare il suo fallimento anticipato, quando l'autore del
modello sa che non c'è alcun punto utile.

Considerate, per esempio, il modello \d+foo quando applicato alla
stringa:

123456bar

Dopo aver corrisposto tutte le sei cifre e dopo aver fallito la
ricorrenza di "foo", l'azione tipica è quella di provare ancora
con solo cinque cifre per \d+, poi con 4, e così via, fino al
fallimento definitivo. Le subpattern "once-only" forniscono i
mezzi per specificare che una volta che una porzione del modello
trova una ricorrenza, non sarà da rivalutare in questo modo, così
il processo giungerà al fallimento per corrispondere "foo" al
primo colpo. Questa notazione è un altro tipo di parentesi
speciali, che cominciano con (?> come in questo esempio:

(?>\d+)bar

Questo tipo di parentesi imprigiona la parte del modello che
contiene una volta che ha trovato una ricorrenza, mentre un
ulteriore fallimento nel modello non è in grado di desistere su se
stesso.

Una descrizione alternativa è che un subpattern di questo tipo
corrisponde la stringa di caratteri che un identico modello, per
conto suo, corrisponderebbe, se ancorato al punto corrente nella
stringa.

I subpattern "once-only" non sono subpattern di cattura.

Once-only subpatterns are not capturing subpatterns. Semplici
casi quali l'esempio sopra possono essere pensati come una replica
che deve inghiottire qualsiasi cosa. Così, mentre sia \d+ che \d+?
sono preparate per adeguare il numero di cifre che corrispondono
al fine di far trovare una ricorrenza al resto del modello,
(?>\d+) può solo corrispondere un'intera senquenza di cifre.

Questa costruzione può sicuramente contenere arbitrariamente
subpattern complicate, e può essere nidificata.

1.14 Subpattern condizionati

E' possibile costringere il processo di corrispondenza a ubbidire
a un subpatter in modo condizionato ovvero a scegliere tra due
alternative di subpattern, dipendendo dal risultato di
un'asserzione, sia nel caso in cui un precedente subpattern di
cattura corrisponda, sia nel caso opposto.

Le due possibili forme di subpattern condizionati sono:

(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

Se la condizione viene soddisfatta, viene usato lo "yes-pattern";
altrimenti il "no-pattern" (se presente). Se ci sono più di due
alternative nel subpattern, si verificherà un errore di
compilazione.

Ci sono due tipi di condizione. Se il testo tra le parentesi
consiste in una sequenza di cifre, allora la condizione è
soddisfatta se il subpattern di cattura di quel numero è stato
precedentemente corrisposto. Considerate il seguente modello, il
quale contiene spazi bianchi non significativi per renderlo più
leggibile (si assume la modalità PCRE_EXTENDED) e per dividerlo in
tre parti per semplicità di analisi:

( \( )? [^()]+ (?(1) \) )

La prima parte corrisponde un'apertura di parentesi facoltativa, e
se quel carattere è presente, imposta essa come la prima
substringa di cattura. La seconda parte corrisponde uno o più
caratteri che non sono tra parentesi. La terza parte è una
subpattern condizionata che processa se il primo set di parentesi
corrisponda o meno. Se corrispondono, ovvero, se la stringa
comincia con un'apertura di parentesi, la condizione è vera, e
così viene applicato lo yes-pattern, mentre una parentesi di
chiusura viene richiesta. Altrimenti, dato che non è presente il
no-pattern, il subpattern non troverà alcuna ricorrenza. In altri
termini, questo modello corrisponde una sequenza di non-parentesi,
occasionalmente racchiuse nelle parentesi.

Se la condizione non è una sequenza di cifre, deve essere
un'asserzione. Questa può essere un'asserzione positiva o
negativa, lookahead o lookbehind. Considerate questo modello,
nuovamente contenente spazi bianchi non significativi, e con le
due alternative nella seconda riga.

(?(?=[^a-z]*[a-z])
\d{2}[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )

La condizione è un'asserzione positiva lookahead che corrisponde
una sequenza opzionale di non-lettere seguite da una lettera. In
altri termini, processa la presenza di almeno una lettera nella
stringa. Se viene trovata una lettera, la stringa viene
corrisposta contro la prima laternativa; altrimenti viene
corrisposta contro la seconda. Questo modello corrisponde le
stringhe in una di queste due forme dd-aaa-dd oppure dd-dd-dd,
dove aaa sono lettere e dd sono cifre.

1.15 Commenti

La sequenza (?# segna l'inizio di un commento che continua fino a
la parentesi di chiusura successiva. Parentesi nidificate non sono
permesse. I caratteri che costituiscono un commento non hanno
alcun ruolo attivo nel funzionamento del modello.

Se è attiva la modalità PCRE_EXTENDED, un carattere # non
trattenuto al di fuori di una classe di caratteri introduce un
commento che continuerà fino al carattere di nuova riga nel
modello.

Alcune voci che possono apparire nei modelli sono più efficienti
di altre. E' più efficiente usare un carattere di classe come
[aeiou] che un set di alternative quali (a|e|i|o|u). In genere,
per la più semplice costruzione che provvede a una determinata
condotta, è anche la più efficiente. Il libro di Jeffrey Friedl
contiene molte discussioni sull'ottimizzazione delle espressioni
regolari per la performance migliore.

1.16 Credits

Questa sezione costituisce semplicemente una traduzione in lingua
italiana delle note sul PCRE - Perl compatible regular expressions
- che si possono trovare in allegato alle ultime versioni di
Xnews. La traduzione è realizzata, al meglio delle conoscenze
dell'autore di questa guida, e ne rappresenta quindi anche un
tentativo di interpretazione.

Le routine per le "regular expression" impiegate in Hamster sono
basate, come già anticipato altrove, sulle porte Win32 del package
"Perl-Compatible Regular Expression (PCRE)" scritto da:

Philip Hazel <ph10@cam.ac.uk>
University Computing Service,
New Museums Site,
Cambridge CB2 3QG, England.
Phone: +44 1223 334714

Copyright (c) 1998 University of Cambridge.


Sezione 2: Espressioni regolari - Perl Regular Expression Tutorial


2.1 Introduzione al tutorial PCRE

Un'espressione regolare è una stringa di caratteri che deve dire
al ricercatore quale stringa (o stringhe) state cercando. Di
seguito sarà spiegato il formato di un'espressione regolare in
dettaglio. Se avete familiarità con il Perl, conoscete già la
sintassi. Se avete familiarità con Unix, dovreste conoscere che ci
sono sottili differenze tra le espressioni regolari in Perl e
quelle in Unix.

2.2 Semplici esempi di espressioni regolari

Nella sua forma più semplice un'espressione regolare è costituita
esattamente da una parola o una frase da cercare. Per esempio:

gauss

dovrebbe corrispondere ogni stringa con la parola "gauss" dentro
di essa. In questo modo, le stringhe con "gauss", "gaussian"
oppure "degauss" saranno corrisposte tanto quanto quelle che
contengono le frasi "de-gauss the monitor" oppure "gaussian
elimination." Altri esempi sono:

carbon

corrisponderà tutte le stringhe con "carbon" o che menzionano
carbon al loro interno (carbonization, hydrocarbons oppure
carbon-based life forms).

hydro

corrisponderà tutte le stringhe con "hydro" all'interno di esse.
Quindi, vanno bene "hydro", "hydrogen" oppure "hydrodynamics"
tanto quanto "hydroplane" oppure "hydroelectric", anche se
costituissero una sola parola in un intero contesto.

oxy

corrisponderà tutte le stringhe con "oxy" all'interno di esse.
Questo potrebbe essere usato per trovare una stringa che parla di
oxygen, boxy houses oppure oxymorons.

top ten

Osservate che gli spazi potrebbero costituire parte
dell'espressione regolare. L'espressione di cui sopra potrebbe
essere usata per trovare "top ten lists", ma anche "stop tension".

2.3 Metacaratteri

Alcuni caratteri hanno un significato speciale per il ricercatore.
Questi caratteri sono chiamati metacaratteri. Benché possano
sembrare confusi in apparenza, essi aggiungono un bel po' di
flessibilità e utilità al ricercatore.

Il punto (.) è comunemente usato come metacarattere. Esso
corrisponde esattamente un carattere, qualunque esso sia. Per
esempio, l'espressione regolare:

2,.-Dimethylbutane

corrisponderà "2,2-Dimethylbutane" e "2,3-Dimethylbutane".
Osservate come il punto misuri esattamente un carattere. Non
corrisponde a una stringa di caratteri, né a una stringa vuota
(null). Così "2,200-Dimethylbutane" e "2,-Dimenthylbutane" non
saranno corrisposte dalle espressioni regolari suindicate.

Ma come si fa se volete cercare una stringa contenente un punto?
Per esempio, supponete di voler cercare riferendovi ai paragrafi.
La seguente espressione regolare potrà funzionare,

3.14 <---sbagliato

ma, oltre a corrispondere "3.14", troverà anche "3514", "3f14"
oppure persino "3+14". In breve, ogni stringa che rispetti, anche
solo in parte, la forma "3x14", dove x è ogni possibile carattere,
sarà corrisposta dall'espressione regolare suindicata.

Per superare questo empasse, introduciamo un secondo
metacarattere, il backslash "\". Il backslash può essere usato per
indicare che il carattere immediatamente alla sua destra deve
essere considerato in modo letterale. Così, per cercare la stringa
"3.14", noi dovremo usare:

3\.14 <---giusto

Questo viene chiamato "quoting" (citazione, l'azione del citare).
Noi dovremmo dire che il punto nell'espressione regolare di cui
sopra è stato citato (quoted, ma anche "quotato" nel gergo
telematico della Usenet italiana). In generale, ogniqualvolta il
backslash è collocato prima di un metacarattere, il ricercatore
tratta il metacarattere letteralmente piuttosto di invocare il suo
speciale significato.

Sfortunatamente, il backslash è usato per altre cose oltre a
quotare metacaratteri. Molti caratteri "normali" godono di un
significato particolare quando sono preceduti da un backslash. La
regola empirica è che, se si quota un metacarattere questo ritorna
al suo significato normale e letterali, mentre se si quota un
carattere normale, questo, associato a \ potrebbe trasformarsi in
un metacarattere.

Diamo un'occhiata ai più comuni metacaratteri. Consideriamo prima
il punto interrogativo. Il punto interrogativo indica che il
carattere immediatamente precedente ad esso deve essere
considerato 0 volte o 1 volta. Così:

m?ethane

corrisponderà sia "ethane" che "methane". In modo analogo,

comm?a

corrisponderà sia "coma" che "comma".

Un altro metacarattere è l'asterisco (*). Questo indica che i
caratteri immediatamente alla sua sinistra possono essere ripetuti
più volte, incluso lo zero. Così:

ab*c

corrisponderà "ac", "abc", "abbc", "abbbc", "abbbbbbbbc" e ogni
stringa che comincia con "a", se seguita da una sequenza di "b" e
terminante con "c".

Il metacarattere "+" indica che il carattere immediatamente
precedente può essere ripetuto una o più volte. Funziona
esattamente come "*", ad eccezione della corrispondenza delle
stringhe nulle. Così:

ab+c

non potrà corrispondere "ac", ma "abc", "abbc", "abbbc",
"abbbbbbbbc" e così via.

I metacaratteri possono essere combinati. Una combinazione comune
include il punto immediatamente seguito dall'asterisco. Questo
viene usato per corrispondere una stringa arbitraria di ogni
possibile lunghezza, compresa quella nulla. Per esempio:

cyclo.*ane

corrisponderà "cyclodecane", "cyclohexane" e persino "cyclones
drive me insane." Ogni stringa che comincia con "cyclo", seguita
da una stringa arbitraria e terminante con "ane" verrà
corrisposta. Osservate che la stringa "null" sarà corrisposta con
la coppia ".*"; così, "cycloane" viene compreso nel campo delle
ricorrenze possibili.

Se volete cercare per articoli che parlano di "cyclodecane" e
"cyclohexane", ma non siete interessati a quelli "cyclones drive
me insane", potreste affiancare tre punti come segue:

cyclo...ane

Questo corrisponderà "cyclodecane" e "cyclohexane", ma non
"cyclones drive me insane". In breve saranno corrisposte tutte le
stringhe lunghe undici caratteri che cominciano per "cyclo" e
terminano per "ane". ("cyclopentane" non sarà corrisposta perché
lunga dodici caratteri e non undici).

Qui ci sono alcuni esempi che concernano il backslash. Osservate
l'importanza della posizione del backslash.

a\.*z

Corrisponde ogni stringa che comincia con "a", seguita da una
serie di punti (oppure nessuno, ovvero serie a lunghezza zero) e
terminano per "z". Così "az", "a.z", "a..z", "a...z"e così via
sono tutti corrisposti.

a.\*z


(Osservate: il backslash e il punto sono stati invertiti in questa
espressione regolare) Corrisponde ogni stringa che comincia con
una "a", seguita da un carattere arbitrario e terminante con "*z".
Così, "ag*z", "a5*z" e "a@*z" sono tutte corrisposte. Solo le
stringhe lunghe quattro caratteri, dove il primo carattere è "a",
il terzo "*", il quarto "z", sono corrisposte.

a\++z

Corrisponde ogni stringa che comincia con "a", seguita da una
serie di caratteri "+" e terminante in "z". Ci deve essere almeno
un "+" tra la "a" e la "z". Così, "az" non è corrisposto, ma
"a+z", "a++z", "a+++z", etc. lo saranno.

a\+\+z

Corrisponde solo la stringa "a++z".

a+\+z

Corrisponde ogni stringa che comincia con una serie di "a",
seguita da un singolo "+" e terminante con "z". Ci deve essere
almeno una "a" all'inizio della stringa. Così, "a+z", "aa+z",
"aaa+z" e così via saranno corrisposte, mentre "+z" no.

a.?e

Corrisponde "ace", "ale", "axe" e ogni altra stringa composta da
tre caratteri cominciante con "a" e terminante in "e"; sarà
corrisposto anche "ae".

a\.?e

Corrisponde "ae" e "a.e". Nient'altro.

a.\?e

Corrisponde ogni stringa di lunghezza pari a quattro caratteri
cominciante con "a" e terminante con "?e". Così, "ad?e", "a1?e" e
"a%?e" saranno corrisposte.

a\.\?e

Corrisponde solo a "a.?e" e nient'altro.

Recentemente si è scritto che il backslash può trasformare
caratteri ordinari in metacaratteri, e viceversa. Uno di questi
caratteri è il metacarattere per riconoscere le cifre, invocabile
con un backslash seguito da una "d" (minuscola sempre), come
questo: "\d". La "d" deve essere minuscola per le ragioni spiegate
più oltre. Tale metacarattere corrisponde esattamente una cifra,
ovvero "0", "1", "2", "3", "4", "5", "6", "7", "8" or "9". Per
esempio, l'espressione regolare:

2,\d-Dimethylbutane

corrisponde "2,2-Dimethylbutane", "2,3-Dimethylbutane" e così via.
Allo stesso modo:

1\.\d\d\d\d\d

corrisponde ogni numero frazionato da 1.00000 a 1.99999 compresi.
Potremmo combinare \d con altri metacaratteri, per esempio:

a\d+z

corrisponde ogni stringa che comincia per a, seguita da una serie
di numeri e terminante in "z". (Osservate che è usato il segno "+"
e quindi "az" non corrisponde.)

La lettera "d" nella stringa "\d" deve essere minuscola. Questo
poiché c'è un altro metacarattere, complemento del precedente, che
si indica con la maiuscola "D" e sarebbe "\D". "\D" identifica
tutto ciò che non è una cifra, così:

a\Dz

corrisponde "abz", "aTz" or "a%z", ma non "a2z", "a5z" oppure
"a9z". Similmente,

\D+

corrisponde ogni stringa non nulla che non contiene caratteri
numerici. Osservate che invertendo da minuscola a maiuscola e
viceversa, invertiamo anche il senso stesso della sequenza
metacarattere. Questo vale anche per altri metacaratteri che
operano insieme alla backslash.

Ci sono tre altre sequenze metacaratteri formato abbinato al
backslash. Il primo è il metacarattere "word", che corrisponde
esattamente una lettera, un numero o il segno di sottolineatura
"_" (underscore). Si scrive "\w". Il suo complemento è "\W", che
corrisponde ogni singolo carattere ad eccezione di lettere, numeri
e "_" (underscore). Così:

a\wz

corrisponde "abz", "aTz", "a5z", "a_z", oppure ogni altra stringa
di tre caratteri che comincia con "a" e finisce per "z", il cui
secondo carattere sia una lettera (maiuscola o minuscola), un
numero oppure "_". Allo stesso modo,

a\Wz

non corrisponde "abz", "aTz", "a5z" oppure "a_z". Corrisponde
"a%z", "a{z", "a?z" oppure ogni stringa di tre caratteri che
comincia con "a" e finisce per "z", il cui secondo carattere non
sia una lettera, un numero oppure "_". (Questo significa che il
secondo carattere deve essere un simbolo o uno spazio vuoto.)

Il metacarattere spazio vuoto "\s" corrisponde esattamente un
carattere vuoto (whitespace). E' definito come spazio,
tabulazione, nuovariga oppure ogni carattere che non usa
inchiostro nel processo di stampa.) Il suo complemento, che
corrisponde ogni carattere visibile (printing a video, per
esempio), è "\S". Così:

a\sz

corrisponderà ogni stringa di tre caratteri che comincia con "a" e
terminante in "z", il cui secondo carattere è uno spazio,
tabulazione o nuova riga. Allo stesso modo,

a\Sz

corrisponde ogni stringa di tre caratteri che comincia con "a" e
finisce con "z" il cui secondo carattere non è uno spazio,
tabulazione o nuova riga. (così, il secondo carattere potrebbe
essere una lettera, numero o simbolo).

Il metacarattere "confine di parola" "\b" corrisponde i confini
delle parole; cioè corrisponde spazi bianchi, punteggiatura e
inizio e fine del testo. Il suo complemento è "\B". Così:

\bcomput

corrisponderà "computer" oppure "computing", ma non
"supercomputer" dato che non c'è nessuno spazio o punteggiatura
tra "super" e "computer". Allo stesso modo:

\Bcomput

non corrisponderà "computer" oppure "computing", a meno di non far
parte di una parola pià grande quale "supercomputer" oppure
"recomputing".

Osservate che "_" viene considerato un carattere "word". Così:

super\bcomputer

non corrisponderà "super_computer".

C'è un ulteriore sequenza di metacaratteri che inizia con lo
backslash, il metacarattere ottale. Il metacarattere ottale appare
in questa forma: "\nnn", dove "n" è un numero da zero a sette.
Questo è usato per specificare caratteri appartenenti al set che
non hanno tipi equivalenti. Per esempio:

\007

corrisponderà tutte le stringhe con incluso un carattere ASCII
"bell" campanello. (bell è individuato dal valore ASCII pari a 7).
E' raro aver bisogno di ricorrere ai metacaratteri ottali.

Ci sono altri tre metacaratteri che possono essere usati. Il primo
è la parentesi graffa. Questo metacarattere segue un carattere
normale e contiene due numeri separati da una virgola e ovviamente
attorniati dalle parentesi "{n,m}". Funziona come il metacarattere
asterisco, ad eccezione che la lunghezza della stringa questa
volta deve essere compresa tra un minimo e un massimo specificato
dai due numeri in parentesi. Così:

ab{3,5}c

corrisponderà "abbbc", "abbbbc" oppure "abbbbbc". Nient'altro.
Allo stesso modo:

.{3,5}pentane

corrisponderà "cyclopentane", "isopentane" oppure "neopentane" ma
non "n-pentane", dato che "n-" è lungo solo due caratteri.

Il metacarattere "alternativa" è rappresentato da una barra
verticale "|". Indica una biforcazione separata da due o più
scelte possibili. Per esempio:

isopentane|cyclopentane

corrisponderà ogni stringa contenente "isopentane" oppure
"cyclopentane" o entrambi. Tuttavia, non corrisponderà "pentane",
"n-pentane" oppure "neopentane."

L'ultimo metacarattere è rappresentato dalla parentesi quadra. Le
parentesi quadre (classi di carattere) corrispondono un solo
carattere se fa parte dell'intervallo o degli intervalli (range)
all'interno delle parentesi([]). Per esempio:

\s[cmt]an\s

corrisponderà "can", "man" e "tan", ma non "ban", "fan" oppure
"pan". Allo stesso modo,

2,[23]-dimethylbutane

corrisponderà "2,2-dimethylbutane" oppure "2,3-dimethylbutane", ma
non "2,4-dimethylbutane", "2,23-dimethylbutane" oppure
"2,-dimethybutane". I range di caratteri possono essere inseriti
usando il trattino (-) in mezzo alle parentesi. Per esempio:

a[a-d]z

corrisponderà "aaz", "abz", "acz" oppure "adz", e nient'altro.
Allo stesso modo:

textfile0[3-5]

corrisponderà "textfile03", "textfile04", oppure "textfile05" e
nient'altro.

Se volete includere un trattino (-) all'interno delle parentesi
con il suo significato letterale, invece di denotare un range,
inseritelo immediatamente prima della parentesi quadra di destra.
Così:

a[1234-]z

e

a[1-4-]z

faranno entrambi la stessa cosa. Corrispondono "a1z", "a2z",
"a3z", "a4z" oppure "a-z" e nient'altro.

Le parentesi quadre possono anche inserire il complemento
dell'intervallo (inversione) con la presenza di un accento
circonflesso (^) immediatamente dopo la parentesi di sinistra.
Così:

textfile0[^02468]

corrisponderà ogni stringa di dieci caratteri che comincia con
"textfile0" e terminante con qualsiasi cosa ad eccezione di un
numero pari. Le inversioni e i range possono essere combinati,
quindi:

\W[^f-h]ood\W

corrisponde ogni stringa alfanumerica di quattro lettere
terminante in "ood" ad eccezione di "food", "good" oppure "hood".
(Così "mood" e "wood" saranno entrambi corrisposti.)

Osservate che dentro le parentesi, di solito le regole di quoting
non vengono applicate e gli altri metacaratteri non sono
disponibili. Gli unici caratteri nelle parentesi quadre che
possono essere quotati sono "[", "]" e, ovviamente, "\". Così:

[\[\\\]]abc

corrisponde ogni stringa di quattro lettere terminante con "abc" e
che inizia con "[", "]" oppure "\".

2.4 Caratteri riservati

A causa del modo di lavorare del ricercatore, i seguenti
metacaratteri non dovrebbero essere usati, anche se sono
considerati validi per il Perl. Essi sono:

^ (permessi all'interno delle parentesi quadre)
$ (permesso all'interno delle parentesi quadre)
\n
\r
\t
\f
\b
( ) (permessi all'interno delle parentesi quadre. Se
desiderate ricercare delle parentesi con del testo,
dovrete quotare quotarle)
\1, \2 ... \9
\B
:
!

2.5 Cose da ricordare

Qui ci sono altre cose che dovreste conoscere circa il
funzionamento delle espressioni regolari.

Le espressioni regolari dovrebbero essere impiegate come ultima
risorsa poiché sono complesse e, inoltre, può richiedere più
lavoro organizzare una ricerca che controllare visivamente un
lungo elenco di ricorrenze (a meno che non prendiate familiarità
con le espressioni regolari).

Il numero delle ricorrenze che possono essere mostrate è limitato
a un massimo di 200. Questo per minimizzare il consumo di risorse
sul vostro sistema.

la ricerca è case insensitive; così

mopac

Mopac

MOPAC

appartengono allo stesso set di stringhe e ognuno di essi potrà
corrispondere "mopac", "MOPAC", "Mopac", "mopaC", "MoPaC", "mOpAc"
e così via. In questo modo non dovrete preoccuparvi dell'uso delle
maiuscole. (Osservate che, tuttavia, i metacaratteri devono avere
la propria lettera. Questo è specialmente importante per i
metacaratteri che hanno un rispettivo complemento.

Al di fuori delle parentesi quadrate, dovete quotare le parentesi
tonde, graffe o quadrate per assumere il loro significato
letterale.