Sintassi delle espressioni regolari

Sintassi delle espressioni regolari -- Descrizione della sintassi utilizzata da PCRE per la definizione delle espressioni regolari

Descrizione

La libreria PCRE è costituita da una serie di funzioni che utilizzano come criterio di riconoscimento le espressioni regolari mutuando la stessa sintassi e la stessa semantica di Perl 5, a parte qualche lieve differenza descritta di seguito. L'attuale implementazione corrisponde alla versione 5.005 di Perl.

Differenze rispetto a Perl

In questo capitolo saranno descritte le differenze rispetto a Perl 5.005.

  1. Per default, lo spazio bianco indica tutti i caratteri riconoscibili dalla funzione isspace() della libreria C, ciò non pregiudica la possibilità di compilare PCRE con un set di caratteri alternativi. Normalmente isspace() riconosce gli spazi, il salto pagina, il carattere 'a capo' (newline), il carattere carriage return, la tabulazione orizzontale e verticale. Perl 5 non riconosce nel set dei caratteri indicati dallo "spazio bianco" la tabulazione verticale. Infatti il carattere di escape \v è stato presente per diverso tempo nella documentazione di Perl, ma di fatto non viene riconosciuto. Tuttavia lo stesso carattere viene trattato come spazio bianco fino alla versione 5.002 di Perl. Nelle versioni 5.004 e 5.005 non viene riconosciuto il carattere \s.

  2. PCRE non supporta occorrenze ripetute in espressioni che "guardano avanti". Perl lo permette, ma non nel modo a cui si possa pensare. Ad esempio, (?!a){3}, non indica che i tre caratteri successivi non debbano essere delle "a", ma indica per tre volte che il carattere successivo non debba essere una "a".

  3. Il riconoscimento di criteri parziali che possono verificarsi all'interno di espressioni che "guardano avanti" negative sono contati, ma i loro riferimenti non sono inseriti nel vettore degli offset. Perl valorizza le sue variabili da qualsiasi criterio che sia riconosciuto prima che l'espressione regolare fallisca nel riconoscere qualcosa, ma questo solo se l'espressione che "guarda avanti" contiene almeno un ramo alternativo.

  4. Sebbene il carattere di 0 binario sia supportato nella stringa in cui si deve svolgere la ricerca, non è ammesso nel testo dell'espressione regolare, questo perché il testo viene passato come stringa C conclusa dal carattere zero. Si può comunque utilizzare la sequenza "\\x00" per richiedere il riconoscimento dello zero binario.

  5. Non sono supportate le seguenti sequenze di escape di Perl: \l, \u, \L, \U, \E e \Q. Infatti queste sono implementate nelle funzioni di gestione delle stringhe di Perl e non nel suo motore di riconoscimento delle espressioni regolari.

  6. L'asserzione di Perl \G non è supportata.

  7. Ovviamente PCRE non supporta il costrutto (?{code}).

  8. Al momento in cui si scrive, in Perl 5.005_02 vi sono alcune particolarità riguardanti la parametrizzazione delle stringhe catturate quando parte del criterio di riconoscimento viene ripetuto. Ad esempio, il riconoscimento di "aba" con il criterio /^(a(b)?)+$/, valorizza $2 con la lettera "b", usando il testo "aabbaa" con il criterio /^(aa(bb)?)+$/ non si ha la valorizzazione di $2. Tuttavia se il criterio di riconoscimento viene variato in /^(aa(b(b))?)+$/, sia $2 che $3 vengono valorizzate. Nelle versione 5.004 di Perl, la variabile $2 viene valorizzata in entrambi i casi, come pure è TRUE in PCRE. Se in futuro Perl cambierà nella gestione anche PCRE potrà cambiare di conseguenza.

  9. Un'altra discrepanza non ancora risolta riguarda il criterio di riconoscimento /^(a)?(?(1)a|b)+$/, che in Perl 5.005_02 riconosce la stringa "a", mentre non accade in PCRE. Tuttavia in entrambi ( Perl e PCRE ) il riconoscimento di "a" con il criterio /^(a)?a/ non valorizza $1.

  10. PCRE prevede alcune estensione alla gestione delle espressioni regolari di Perl:

    1. Sebbene le asserzioni che "guardano indietro" richiedano testi di lunghezza fissa, è ammesso che ciascun ramo alternativo del criterio di ricerca possa intercettare stringhe di lunghezza differente. Al contrario Perl 5.005 richiede che tutte le stringhe abbiamo la stessa lunghezza.

    2. Se viene settato PCRE_DOLLAR_ENDONLY e non viene attivato PCRE_MULTILINE, il meta-carattere $ indica soltanto la fine della stringa.

    3. Se si attiva PCRE_EXTRA, un carattere backslash (\) seguito da una lettera che non abbia un significato speciale genera un errore.

    4. Se si attiva PCRE_UNGREEDY, si inverte la "voracità" delle occorrenze, in modo da non essere voraci per default, ma lo tornano ad essere se seguiti da "?".

Dettagli sulle espressioni regolari

Introduzione

Di seguito verrà descritta la sintassi e la semantica delle espressioni regolari così come sono supportate da PCRE. La descrizione delle espressioni regolari può essere reperita anche nei manuali di Perl e in numerosi altri libri, alcuni dei quali ricchi di esempi. Ad esempio il libro di Jeffrey Friedl intitolato "Mastering Regular Expressions", edito da O'Reilly (ISBN 1-56592-257-3), li tratta in modo dettagliato. Questa descrizione, invece, viene intesa come una documentazione di riferimento. Una espressione regolare è un criterio utilizzato per identificare parti di un testo partendo da sinistra verso destra. La maggior parte delle lettere identifica se stessa nel testo oggetto del riconoscimento. Ad esempio il banale testo La volpe veloce intercetta la parte del testo uguale all'espressione regolare.

Meta-caratteri

La potenza delle espressioni regolari deriva dalla possibilità di inserire criteri alternativi oppure ripetuti. Questi sono codificati nel criterio di ricerca tramite l'uso di meta-caratteri, lettere che non indicano se stesse, ma sono interpretate in modo particolare.

Esistono due differenti set di meta-caratteri: quelli che sono riconosciuti ovunque tranne che all'interno di parentesi quadrate, e quelli che sono riconosciuti all'interno di parentesi quadrate. I meta-caratteri che si usano all'esterno delle parentesi quadrate sono:

\

carattere di escape generico con diversi utilizzi

^

indica l'inizio del testo (o della linea in modalità multi-linea)

$

indica la fine del testo (o della linea in modalità multi-linea)

.

indica qualsiasi carattere tranne "a capo" (per default)

[

carattere di inizio della definizione di classe

]

carattere di fine della definizione di classe

|

inizio di un ramo alternativo

(

inizio di un criterio di riconoscimento parziale

)

fine del criterio di riconoscimento parziale

?

estende il significato di (, oppure 0 o 1 occorrenza, oppure occorrenza minima

*

0 o più occorrenze

+

1 o più occorrenze

{

inizia l'intervallo minimo/massimo di occorrenze

}

termina l'intervallo minimo/massimo di occorrenze

La parte del criterio che si trova tra parentesi quadrate viene detta "classe di caratteri". In una classe di caratteri i meta-caratteri previsti sono:

\

carattere di escape generico con diversi utilizzi

^

nega la classe, ma solo se posto all'inizio

-

indica un intervallo

]

chiude la classe di caratteri

Le sezioni seguenti descriveranno l'uso di ciascuno dei meta-caratteri.

Backslash

Il carattere backslash (\) ha diversi utilizzi. Primo uso: se viene anteposto a caratteri non alfanumerici, rimuove gli eventuali significati speciali che il carattere può avere. Questo utilizzo di backslash come carattere di escape può essere svolto sia all'interno delle classi di caratteri sia all'esterno.

Ad esempio, un criterio che deve riconoscere il carattere "*" conterrà "\*". Ciò si applica indipendentemente dal carattere seguente, sia esso interpretabile come meta-carattere o meno. Nel caso in cui un carattere non alfanumerico debba identificare se stesso è opportuno farlo precedere dal "\". In particolare per identificare un backslash occorre scrivere "\\".

Se nel criterio di riconoscimento si specifica l'opzione PCRE_EXTENDED, lo spazio bianco (diversamente da quando si trova all'interno di una classe di caratteri), e i caratteri posti tra "#" e un "a capo" all'esterno di una classe di caratteri sono ignorati. Un backslash può essere usato come escape per inserire uno spazio bianco od il carattere "#" come parte del criterio di riconoscimento.

Un secondo utilizzo del backslash consiste nel codificare in modo visibile dei caratteri non visibili. Non ci sono restrizioni nella presenza di caratteri non-stampabili, a parte lo zero binario terminante la stringa dell'espressione regolare. Di seguito saranno elencate le sequenze di caratteri che è preferibile utilizzare per la loro semplicità al posto delle corrispondenti codifiche binarie.

\a

allarme, il carattere BEL (hex 07)

\cx

"control-x", dove x è un qualsiasi carattere

\e

escape (hex 1B)

\f

salto pagina (hex 0C)

\n

"a capo" (newline) (hex 0A)

\r

carriage return (hex 0D)

\t

tabulazione (hex 09)

\xhh

carattere il cui codice esadecimale è hh

\ddd

carattere il cui codice ottale è ddd, oppure riferimento all'indietro

Il preciso effetto di "\cx" è il seguente: se "x" è una lettera minuscola, viene convertita in lettera maiuscola. In pratica viene invertito il sesto bit (hex 40) del carattere. Quindi "\cz" diventa hex 1A, ma "\c{" diventa hex 3B, mentre "\c;" diventa hex 7B.

Dopo la sequenza "\x", saranno letti due numeri esadecimali (per le lettere non si distingue tra maiuscolo e minuscolo)

Dopo la sequenza "\0" saranno lette due cifre in ottale. In entrambi i casi se vi sono meno di due cifre, saranno usati i numeri presenti. Pertanto la sequenza "\0\x\07" indica 2 zeri binari seguiti dal carattere BEL. Occorre accertarsi di passare le cifre necessarie dopo lo zero iniziale se il carattere che segue può essere scambiato per una cifra in ottale.

Più complicata è la gestione del backslash seguito da una cifra diversa da 0. Al di fuori di una classe di caratteri, PCRE tratta le cifre che trova come numeri decimali. Se il numero è inferiore a 10, oppure vi sono state almeno altrettante parentesi sinistre, la sequenza viene considerata come un riferimento all'indietro. Più avanti, nella parte dei criteri parziali, sarà descritto come funzionano questi riferimenti.

All'interno di una classe di caratteri, oppure nel caso in cui il numero decimale è maggiore di 9 e non ci sono stati altrettanti criteri parziali, PCRE rilegge le prime 3 cifre seguenti il backslash in ottale e genera il carattere dagli 8 bit meno significativi del valore ottenuto. Ogni altra cifra seguente indica se stessa. Ad esempio:

\040

è un'altro modo per indicare uno spazio

\40

ha il medesimo significato dell'esempio precedente che non vi sono 40 sotto-criteri

\7

è sempre un riferimento all'indietro

\11

può essere un riferimento all'indietro o un'altro modo per indicare il carattere di tabulazione

\011

è ancora il carattere di tabulazione

\0113

il carattere di tabulazione seguito da "3"

\113

è il carattere con il codice ottale 113 (poiché non ci possono essere più di 99 riferimenti all'indietro)

\377

è un byte con tutti i bit a 1

\81

può essere un riferimento all'indietro o uno zero binario seguito da "8" e da "1"

Occorre rilevare che valori ottali maggiori di 100 non devono essere preceduti dallo zero, questo perché la libreria considera solo tre cifre.

Tutte le sequenze che definiscono il valore di un singolo byte possono essere utilizzate sia all'interno sia all'esterno delle classe di caratteri. Inoltre, all'interno delle classi di caratteri, la sequenza "\b" viene interpretata come carattere di backspace (hex 08), mentre all'esterno ha un'altro significato (come descritto più avanti).

Il terzo utilizzo possibile per il backslash consiste nello specificare il tipo di carattere:

\d

qualsiasi cifra decimale

\D

qualsiasi carattere che non sia una cifra decimale

\s

qualsiasi carattere identificato come spazio bianco

\S

qualsiasi carattere che non sia identificato come spazio bianco

\w

qualsiasi carattere che sia una "parola" (word)

\W

qualsiasi carattere che non sia una "parola" (word)

Ciascuna coppia di sequenze di escape suddivide il set completo dei caratteri in due insiemi disgiunti. Un dato carattere deve essere identificato da un solo insieme di ciascuna coppia.

I caratteri definiti "parole" sono quelle lettere o cifre o il carattere underscore (_), cioè qualsiasi carattere che possa essere parte di una "parola" in Perl. In PCRE le definizioni di lettere e cifre vengono gestite tramite le tabelle dei caratteri, che possono variare in base a specifici parametri di localizzazione (vedere il paragrafo intitolato "Supporto alle localizzazioni"). Ad esempio, nella localizzazione fr (relativa alla Francia), qualche codice carattere maggiore di 128 è utilizzato per le lettere accentate, e queste sono identificate tramite la sequenza \w.

Queste sequenze di tipi di caratteri possono apparire sia all'interno sia all'esterno delle classi di caratteri. Ciascuna di esse identifica un carattere del tipo appropriato. Se durante la fase di identificazione di un testo, si giunge al termine della stringa in cui si esegue il riconoscimento e si hanno ancora di queste sequenze da incrociare, l'operazione di identificazione fallirà perché, ovviamente, non vi sono più caratteri in cui riconoscere le suddette sequenze.

Il quarto utilizzo per il backslash riguarda la costruzione di particolari asserzioni. L'asserzione è una condizione che deve essere soddisfatta ad un certo punto del riconoscimento, senza "consumare" caratteri dalla stringa oggetto del riconoscimento. Più avanti verranno descritte asserzioni più complicate, costruite tramite l'uso di sotto-criteri di riconoscimento, per ora saranno illustrate delle semplici asserzioni costruite con il backslash:

\b

limite di una parola

\B

non limite di una parola

\A

inizio dell'oggetto di ricerca (a prescindere dalla modalità multi-linea)

\Z

fine dell'oggetto di ricerca oppure newline alla fine (a prescindere dalla modalità multi-linea)

\z

fine dell'oggetto di ricerca (a prescindere dalla modalità multi-linea)

Queste asserzioni non possono apparire all'interno di una classe di caratteri (attenzione che la sequenza "\b" all'interno di una classe di caratteri indica il carattere backspace).

Viene definito limite di una parola la posizione nella stringa oggetto della ricerca, nella quale il carattere corrente ed il carattere precedente non soddisfano la sequenza \w o la sequenza \W (ad esempio uno soddisfa la sequenza \w e l'altro carattere soddisfa la sequenza \W), oppure quella posizione, all'inizio o alla fine della stringa, nella quale rispettivamente il primo o l'ultimo carattere soddisfa la sequenza \w.

Le asserzioni \A, \Z e \z differiscono dai tradizionali caratteri "^" e "$" (descritti di seguito) per il fatto di identificare sempre l'inizio o la fine della stringa oggetto di ricerca a prescindere da quale opzione sia stata attivata. Infatti queste asserzioni non sono alterate da PCRE_NOTBOL oppure da PCRE_NOTEOL. La differenza tra \Z e \z consiste nel fatto che \Z identifica sia il carattere precedente il newline posto al termine della stringa sia la fine della stringa, mentre \z identifica solo la fine.

I caratteri "^" e "$"


     In condizioni normali, il carattere "^", posto all'esterno di 
     una classe di caratteri, indica un asserzione che è vera soltanto
     se il punto da cui si inizia a identificare il testo si trova
     all'inizio della stringa oggetto della ricerca. Al contrario,
     se il carattere "^" si trova all'interno di una classe di 
     caratteri, assume altri significati (vedere i capitoli seguenti).

     Non è necessario che il carattere "^" sia la prima lettera
     del criterio di riconoscimento nei casi in cui si utilizzino
     dei criteri di riconoscimento alternativi. Tuttavia è necessario
     che sia la prima lettera nei rami alternativi in cui compare.
     Se si inserisce il carattere "^" in tutte le alternative, caso
     che ricorre quando si vuole riconoscere un testo a partire 
     dall'inizio della stringa, si dice che si è costruito un criterio
     di ricerca "ancorato". (Esistono anche altre costruzioni che
     portano all'ancoraggio di un criterio di ricerca).

     Il carattere dollaro "$" è una asserzione che è TRUE soltanto
     se il punto a cui si è arrivati ad identificare il testo si 
     trova alla fine della stringa oggetto della ricerca, o 
     nella lettera immediatamente precedente il carattere di "a capo",
     che (per default) è l'ultimo carattere del testo. Il dollaro "$"
     non deve essere necessariamente l'ultima lettera di un criterio 
     di riconoscimento se in questo si sono utilizzati dei criteri
     alternativi. Deve, comunque, essere l'ultima lettera nei criteri
     ove compare. Il carattere dollaro "$" non ha significati speciali 
     all'interno di una classe di caratteri.

     Il comportamento del simbolo "$" può essere variato in modo
     da identificare la reale fine della stringa oggetto di ricerca
     attivando il flag PCRE_DOLLAR_ENDONLY 
     durante la compila o durante la fase di riconoscimento. Ciò
     non influisce sull'asserzione \Z.

     Il comportamento dei simboli "^" e "$" può essere influenzato
     dall'opzione PCRE_MULTILINE. Quando viene 
     attivata, questi caratteri identificano rispettivamente,
     oltre ai tradizionali inizio e fine testo, la lettera immediatamente 
     successiva ed immediatamente precedente il carattere "\n" presente 
     all'interno della stringa oggetto di ricerca. Per esempio il 
     criterio /^abc$/ riconosce il testo "def\nabc" solo in modalità
     multi-linea. Di conseguenza i criteri di riconoscimento che
     sono "ancorati" in modalità singola linea, non lo sono in modalità
     multi-linea. L'opzione PCRE_DOLLAR_ENDONLY 
     viene ignorata se si attiva il flag PCRE_MULTILINE .

     Occorre rilevare che le sequenze \A, \Z e \z possono essere 
     utilizzate per riconoscere l'inizio e la fine del testo in
     entrambe le modalità, e, se tutti i criteri alternativi 
     iniziano con \A, si ha ancora un criterio "ancorato"
     a prescindere che sia attivata o meno l'opzione PCRE_MULTILINE.
     

FULL STOP


     Il carattere punto ".", all'esterno di una classe di caratteri,
     identifica qualsiasi carattere, anche quelli non stampabili,
     ma (per default) non il carattere "a capo". Invece se si 
     abilita l'opzione PCRE_DOTALL 
     si avrà anche il riconoscimento del carattere "a capo".
     La gestione del simbolo "." è svincolata dalla gestione dei
     simboli "^" ed "$", l'unica relazione che possono avere riguarda
     il carattere "a capo". Il punto "." non ha significati speciali
     all'interno delle classi di caratteri.

     

Parentesi quadrate


     Un parentesi quadrata aperta "[" inizia una classe di caratteri;
     una parentesi quadrata chiusa "]" termina la definizione
     della classe. Di suo il carattere di parentesi quadrata chiusa 
     non ha significati speciali. Se occorre inserire la parentesi
     chiusa all'interno di una classe di caratteri, questa deve 
     essere la prima lettera (ovviamente deve seguire il carattere "^", 
     se presente) oppure deve essere preceduta dal carattere di escape "\".

     Una classe di caratteri identifica un singolo carattere nella
     stringa oggetto di ricerca; il carattere deve comparire nel
     set di caratteri definito dalla classe, a meno che il primo 
     carattere della classe non sia l'accento circonflesso "^",
     in tal caso il carattere non deve essere nel set definito 
     dalla classe. Se è richiesto l'inserimento del carattere "^"
     nel set definito dalla classe, questo non deve essere la 
     prima lettera dopo la parentesi di apertura, oppure deve
     essere preceduto dal carattere di escape (\).

     Ad esempio, la classe [aeiou] identifica ogni vocale minuscola,
     mentre [^aeiou] identifica tutti i caratteri che non siano delle
     vocali minuscole. Occorre notare che il simbolo "^" è un modo
     pratico per indicare i caratteri che sono nella classe, citando
     quelli che non lo sono. Questa non è una asserzione: consuma
     un carattere della stringa oggetto di ricerca e fallisce se ci
     si trova alla fine del testo. 

     In un riconoscimento senza distinzione tra minuscole e maiuscole,
     ogni lettera della classe identifica sia la versione maiuscola
     sia la minuscola. Così, ad esempio, la classe [aeiou] identifica
     sia "A" sia "a", e, in questo caso, [^aeiou] non identifica "A",
     mentre con la distinzione delle maiuscole [^aeiou] identifica
     la lettera "A".

     Il carattere di "a capo" (newline) non viene trattato in
     modo speciale nelle classi di caratteri, indipendentemente
     dalle opzioni PCRE_DOTALL o PCRE_MULTILINE.
     La classe [^a] riconosce sempre il carattere "a capo".

     Il segno meno (-) può essere usato per definire un intervallo
     all'interno della classe. Ad esempio, [d-m] identifica ogni
     lettera compresa tra d ed m inclusi. Se occorre inserire il
     segno meno (-) come carattere da riconoscere o lo si fa 
     precedere dal carattere di escape (\), oppure lo si mette in 
     una posizione tale che non possa essere identificato come 
     definizione di un intervallo (ad esempio all'inizio o alla fine 
     della definizione della classe).
     
     Non è possibile usare il carattere "]" come limite di un
     intervallo. Un criterio definito come [W-]46], viene inteso 
     come una classe di due caratteri (W e -) seguita dalla stringa
     46], in tal modo sarebbero riconosciuti i testi "W46]" oppure "-46]".
     Quindi è necessario precedere la lettera "]" con il carattere di
     escape (\), in questo modo [W-\]46], viene interpretata 
     correttamente come una singola classe contenente un range seguito
     da due caratteri separati. In alternativa, per delimitare l'intervallo 
     si può utilizzare la notazione ottale di "]".

     Gli intervalli utilizzano la sequenza di caratteri ASCII.
     Inoltre possono essere utilizzati per definire caratteri con 
     specifica numerica (ad esempio [\000-\037]). Nei casi in cui
     si abiliti il riconoscimento senza distinzione tra lettere 
     maiuscole e minuscole, gli intervalli comprendenti lettere
     identificano sia la lettera maiuscola che minuscola. Ad esempio,
     [W-c] è equivalente ad [][\^_`wxyzabc] (con il riconoscimento 
     a prescindere dalla lettera maiuscole e minuscole), e, se
     si utilizza la tabella dei caratteri locali francesi "fr",
     [\xc8-\xcb] identifica la lettera "e" accentata sia maiuscola
     sia minuscola.

     Nelle classi di caratteri si possono utilizzare le sequenze
     \d, \D, \s, \S,  \w e \W per aggiungere altri tipi di caratteri
     alla classe. Ad esempio, [\dABCDEF] riconosce qualsiasi cifra 
     esadecimale. Il carattere "^" può essere utilizzato con i caratteri
     maiuscoli per indicare un set di caratteri più ristretto
     che l'identificazione del set di caratteri minuscoli. Ad 
     esempio, la classe [^\W_] identifica qualsiasi lettera o cifra
     ma non il trattino basso (_).

     Tutti i caratteri non alfabetici, eccetto \,  -,  ^ (posto
     all'inizio) e ] non sono speciali per la classi di caratteri,
     e non sono dannosi se preceduti dal caratteri di escape (\).
     

Barra verticale (|)


     La barra verticale (|) viene utilizzata per separare criteri 
     di riconoscimento alternativi. Ad esempio il seguente criterio
 
       gilbert|sullivan

     può riconoscere "gilbert" oppure "sullivan". Ci possono essere
     innumerevoli alternative, compresa un'alternativa vuota (per 
     identificare una stringa vuota). Il processo di riconoscimento 
     prova tutte le alternative possibili (da sinistra a destra)
     fino a quando non ne trova una che sia soddisfatta. Se le
     alternative sono nella definizione di un criterio parziale
     il riconoscimento ha successo quando avviene su tutto il criterio.
     

Settaggio delle opzioni interne


     Le opzioni PCRE_CASELESSPCRE_MULTILINE ,  
     PCRE_DOTALL e PCRE_EXTENDED 
     possono essere cambiate "al volo" dall'interno del criterio di 
     riconoscimento, utilizzando le sequenze di lettere definite per 
     queste opzioni in Perl, racchiuse tra "(?" ed ")". Le lettere 
     utilizzabili sono:

       i  per PCRE_CASELESS 
       m  per PCRE_MULTILINE 
       s  per PCRE_DOTALL 
       x  per PCRE_EXTENDED 

     Ad esempio, (?im) abilita il riconoscimento senza distinzione
     tra lettere maiuscole e minuscole e la modalità multi-linea.
     E' anche possibile disabilitare queste opzioni facendo precedere
     la lettera dal segno meno (-), o combinare l'attivazione con la
     disattivazione come nel caso (?im-sx), in cui si attiva PCRE_CASELESS e 
     PCRE_MULTILINE e si disattiva PCRE_DOTALL e PCRE_EXTENDED.
     Se la lettera compare sia prima che dopo il segno meno (-)
     l'opzione resta disabilitata.

     L'ambito di validità delle opzioni dipende da dove sono
     i flag di abilitazione/disabilitazione nel criterio di ricerca.
     Nei casi in cui il settaggio di un'opzione avvenga all'esterno
     di un qualsiasi criterio parziale (come definito in seguito) gli 
     effetti sono  medesimi di quando l'attivazione/disattivazione 
     avviene all'inizio del criterio di riconoscimento. Gli esempi
     seguenti si comportano tutti allo stesso modo:

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

     In questi esempi si attiva PCRE_CASELESS  
     per il criterio "abc". In altre parole, questo settaggio compiuto 
     al primo livello si applica a tutto il criterio (a meno che non
     vi siano altre variazioni nelle sotto-regole di riconoscimento).
     Qualora vi siano più settaggi per lo stesso parametro, viene
     utilizzato quello più a destra.

     Se si inserisce la variazione di un'opzione in una sotto-regola
     gli effetti sono differenti. Questa è una variazione rispetto al 
     comportamento di Perl 5.005. Una variazione apportata all'interno 
     di una sotto-regola, vale solo per la parte della sotto-regola 
     che segue la variazione, pertanto

       (a(?i)b)c

     identifica abc, aBc e nessuna altra stringa ( si assume che
     PCRE_CASELESS non sia usato).  
     Da ciò deriva che le opzioni possono avere comportamenti differenti
     nelle varie parti del criterio di riconoscimento. Ogni variazione
     apportata ad una ramo alternativo del criterio viene estesa alle
     alternative successive della medesima sotto-regola. Ad esempio,

       (a(?i)b|c)

     identifica "ab", "aB", "c" e "C", anche se per identificare "C"
     viene scartato il primo ramo prima di incontrare il settaggio
     dell'opzione. Questo accade perché gli effetti dei settaggi 
     vengono inseriti nella fase di compila. Diversamente si avrebbero
     dei comportamenti molto bizzarri.

     Le opzioni specifiche di PCRE PCRE_UNGREEDY e PCRE_EXTRA 
     possono essere variate nel medesimo modo delle opzioni 
     Perl compatibili, utilizzando rispettivamente i caratteri 
     U e X. Il flag (?X) è particolare poiché deve comparire 
     prima di qualsiasi opzione esso attivi anche quando si 
     trova al primo livello. E' opportuno inserirlo all'inizio.

     

Sotto-regole


     Le sotto-regole sono delimitate dalle parentesi tonde e
     possono essere annidate. La definizione di una parte di
     una regola di riconoscimento come sotto-regola può servire a:

     1. Localizzare un set di alternative. Ad esempio nel seguente
     criterio di riconoscimento

       cat(aract|erpillar|)

     si riconosce una tra le parole "cat", "cataract" oppure "caterpil-
     lar".  Se non fossero state usate le parentesi, il criterio
     avrebbe permesso il riconoscimento delle parole "cataract",
     "erpillar" oppure una stringa vuota.

     2. Identificare e catturare parte del testo riconosciuto 
     dalla sotto-regola (come illustrato in seguito). Quando 
     il riconoscimento dell'intero criterio ha avuto successo, 
     le porzioni della stringa oggetto della ricerca identificate
     dalle sotto-regole sono restituite alla funzione chiamante
     tramite l'argomento vettore della funzione
     pcre_exec(). Per determinare il numero ordinale
     di ciascuna sotto-regola si contano le parentesi aperte da
     sinistra verso destra partendo da 1.

     Ad esempio, se si esegue un riconoscimento nella frase 
     "the red king" con il seguente criterio

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

     si ottengono i testi "red king", "red" e "king", rispettivamente
     identificati dalla sotto-regola 1, 2 e 3.
     
     Il fatto che le parentesi tonde adempiano a due funzioni non
     sempre porta a situazioni comprensibili. Spesso capita di 
     dovere raggruppare delle sotto-regole senza per questo essere
     richiesta la cattura del testo. A tale scopo l'uso della 
     sequenza "?:" dopo la parentesi di apertura permette di indicare
     che questa sotto-regola non deve catturare il testo, e non deve essere
     conteggiata nel numero d'ordine delle sotto-regole di cattura.
     Ad esempio, applicando il criterio  

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

     alla frase "the  white  queen", si catturano i testi "white queen" 
     e  "queen",  rispettivamente numerati 1 e 2. Il numero massimo
     di testi catturabili è 99, il numero massimo di sotto-regole,
     a prescindere che siano di cattura o meno, è 200.

     Come utile abbreviazione, nei casi in cui l'attivazione di
     alcune opzioni debba essere fatta all'inizio di una sotto-regola
     non di cattura, la lettera dell'opzione può comparire tra la 
     "?" e ":". Pertanto i due criteri

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

     riconoscono esattamente lo stesso set di parole. Poiché i rami 
     alternativi sono provati da sinistra verso destra, e le opzioni
     non sono azzerate fino a quando non si è conclusa la sotto-regola,
     una opzione attivata in un ramo alternativo si applica a tutte
     le alternative che seguono. Pertanto, nell'esempio di prima, sia
     la parola "SUNDAY" che la parola "Saturday" sono testi
     identificati correttamente.
     

Ripetizioni


     Le ripetizioni sono il numero delle occorrenze che possono
     essere indicate dopo i seguenti elementi:

       un singolo carattere, possibilmente preceduto dal carattere di escape (\)
       il metacarattere .
       una classe di caratteri
       un riferimento all'indietro (vedere la sezione successiva)
       una sotto-regola (a meno che non si tratti di una asserzione - 
       vedere più avanti)

     In generale una occorrenza specifica un numero minimo e massimo
     di riconoscimenti previsti tramite la specifica dei due limiti,
     posti tra parentesi graffe e separati da una virgola. Entrambi i numeri
     devono essere minori di 65536 ed il primo deve essere minore o 
     uguale rispetto al secondo. Ad esempio:

       z{2,4}

     identifica  "zz", "zzz" oppure "zzzz". La parentesi graffa chiusa
     di suo non rappresenta un carattere speciale. Se si omette il 
     secondo numero, ma si lascia la virgola, non si indica un 
     limite superiore; se sia la virgola sia il secondo numero sono
     omessi, l'occorrenza specifica l'esatto numero di riconoscimenti
     richiesti. Il criterio

       [aeiou]{3,}

     identifica almeno 3 o più vocali consecutive, mentre

       \d{8}

     identifica esattamente 8 cifre. Una parentesi graffa aperta
     che compaia in una posizione in cui non sia prevista una 
     occorrenza, o che comunque non sia riconducibile alla sintassi
     di una occorrenza, viene tratta come il carattere "{". Ad 
     esempio {,6} non indica delle occorrenze, ma una stringa di
     4 caratteri.

     L'indicazione {0} è permessa. Indica di comportarsi come se 
     l'elemento precedente all'occorrenza non fosse presente.

     Per praticità (e compatibilità verso il passato) si usano 3
     abbreviazioni per le occorrenze più comuni:

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

     E' anche possibile creare un ciclo infinito facendo seguire
     ad una sotto-regola che non identifica alcun carattere una
     occorrenza priva di limite superiore. Ad esempio:

       (a?)*

     Le versioni precedenti di Perl e di PCRE segnalavano un errore
     durante la fase di compila per questi criteri. Tuttavia, poiché
     vi sono casi dove questi criteri possono essere utili, queste
     regole sono accettate, ma, se la ripetizione non riconosce 
     alcun carattere, il ciclo viene interrotto.   

     Per default le occorrenze sono "bramose", infatti identificano
     più testi possibile (fino al numero massimo permesso), senza
     per questo fare fallire il riconoscimento della parte rimanente
     del criterio di ricerca. Il classico esempio dove questo comportamento
     può essere un problema, riguarda il riconoscimento dei commenti
     nei programmi C. Questi compaiono tra le sequenze /* ed */,
     ma all'interno, nel commento, si possono usare sia il carattere
     *, sia il carattere /. Il tentativo di individuare i commenti C
     con il seguente criterio    

       /\*.*\*/

     se applicato al commento

       /* primo commento */  nessun commento  /* secondo commento */

     non ha successo, perché identifica l'intera stringa a causa
     della "bramosia" dell'elemento ".*".

     Tuttavia, se un'occorrenza è seguita da un punto interrogativo,
     questa cessa di essere "bramosa", e identifica il numero
     minimo di testi permessi. Pertanto il criterio

       /\*.*?\*/

     si comporta correttamente con i commenti C. Il significato 
     delle varie occorrenze non è stato cambiato, si è soltanto
     modificato il numero delle occorrenze da riconoscere. Attenzione
     a non confondere questo uso del punto interrogativo con il
     suo proprio significato. Dati i due utilizzi del ?, può
     anche capitare di averli entrambi come in     

       \d??\d

     che, preferibilmente, identifica una cifra, ma può riconoscerne
     due se questa è l'unica via per soddisfare il riconoscimento
     dell'intero criterio.     

     Se si attiva l'opzione PCRE_UNGREEDY
     (un'opzione disponibile anche in Perl), per default le occorrenze
     non sono "bramose", ma ogni singola occorrenza può essere 
     resa "bramosa" se seguita dal punto interrogativo. In altre
     parole si è invertito il normale comportamento.

     Quando si indica un numero minimo di occorrenze maggiore di 1,
     per una sotto-regola posta tra parentesi, oppure
     si indica un numero massimo di occorrenze, la fase di
     compila richiede più spazio in proporzione ai valori 
     minimo e massimo.     

     Se un criterio inizia con .* oppure .{0,} e si è attivata
     l'opzione PCRE_DOTALL 
     (equivalente al /s di Perl), permettendo al . di identificare
     il carattere di "a capo", si dice che il criterio è implicitamente
     ancorato, perché qualsiasi elemento che segue sarà confrontato
     con ciascun carattere della stringa oggetto della ricerca,
     e pertanto non vi è nessuna posizione, a parte la prima, da
     cui ripartire per ritentare il riconoscimento dell'intero criterio. 
     PCRE tratta tale criterio come se fosse preceduto dalla sequenza
     \A. Nei casi in cui è noto a priori che la stringa oggetto di 
     ricerca non contiene caratteri di "a capo", vale la pena di 
     attivare l'opzione PCRE_DOTALL
     se il criterio di ricerca inizia con ".*", per ottenere 
     questa ottimizzazione, oppure, in alternativa, usare "^"
     per indicare in modo esplicito un ancoraggio.

     Quando si ripete una sotto-regola di cattura, il testo 
     estrapolato è la parte identificata dall'iterazione finale.
     Ad esempio se il criterio   

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

     viene applicato al testo "tweedledum tweedledee", il testo 
     estrapolato sarà "tweedledee". Tuttavia se vi sono delle
     sotto-regole annidate, il testo catturato può essere 
     determinato dalle iterazioni precedenti. Ad esempio nel 
     criterio 
     
       /(a|(b))+/

     applicato a "aba", la seconda stringa catturata è "b".
     

Riferimenti all'indietro


     Esternamente ad una classe di caratteri, un backslah (\) 
     seguito da una o più cifre maggiori di 0 è un riferimento
     all'indietro verso testi catturati precedentemente (ad esempio
     alla sinistra rispetto a dove ci si trova), conteggiati tramite
     il numero delle parentesi chiuse precedenti.

     Tuttavia, se il numero che segue il backslash (\) è un valore
     inferiore a 10, si assume che si tratti sempre di un riferimento
     all'indietro, e pertanto viene generato un errore se nel criterio
     non vi sono almeno altrettante parentesi chiuse di sotto-regole
     di cattura. In altre parole per i numeri inferiori a 10 non è 
     necessario che il numero parentesi precedenti (a sinistra)
     alla sotto-regola sia pari o maggiore al numero indicato.
     Vedere la sezione relativa al backslash per informazioni su
     come gestire le cifre seguenti il backslash.

     Un riferimento all'indietro identifica ciò che è già
     stato catturato dalla sotto-regola, e non ciò che la
     sotto-regola stessa possa riconoscere. Ad esempio il
     criterio

       (sens|respons)e and \1ibility

     può riconoscere "sense and sensibility" oppure "response and
     responsibility", ma non il testo "sense  and  responsibility". 
     Se al momento del riferimento all'indietro, è attiva la distinzione
     tra lettere maiuscole e minuscole, il formato della lettera 
     diventa rilevante. Ad esempio,

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

     può identificare "rah rah" e "RAH RAH", ma non "RAH  rah",  
     anche se la sotto-regola originale eseguiva dei riconoscimenti
     a prescindere dalle lettere maiuscole e minuscole.

     Nella medesima sotto-regola si possono avere più di un riferimento
     all'indietro. Se una sotto-regola non viene utilizzata in
     un particolare riconoscimento, un riferimento a questa
     ha sempre esito  negativo. Ad esempio il criterio

       (a|(bc))\2

     non avrà mai successo se l'identificazione della stringa 
     inizia con "a" e non con "bc". Dato che sono possibili fino a 99
     riferimenti all'indietro, tutte le cifre che seguono un backslash
     (\) sono considerate come parte di un potenziale numero di
     riferimento. Se il criterio continua con altri caratteri 
     numerici, occorre stabilire un carattere per delimitare il
     numero del riferimento. Se si attiva l'opzione PCRE_EXTENDED 
     questo carattere può essere lo spazio. Altrimenti si può usare 
     un commento vuoto.

     Un riferimento all'indietro non ha successo se viene inserito 
     in una sotto regola prima che sia applicata. Con questo si 
     intende, ad esempio, che (a\1) non avrà mai successo, ma, nel
     caso di una sottoregola ripetuta, si avrà un riscontro positivo.
     Ad esempio

       (a|b\1)+

     identificherà qualsiasi numero di "a", ma anche "aba" oppure
     "ababaa" eccetera. In pratica a ciascuna iterazione della 
     sotto-regola il riferimento andrà a sostituire la stringa riconosciuta
     tramite la sotto-regola dell'iterazione precedente. Affinchè
     il tutto funzioni, è necessario che la prima iterazione sia
     identificata senza l'ausilio del riferimento "all'indietro".
     Ciò può essere ottenuto o usando casi alternativi, come nell'esempio
     precedente, o usando le occorrenze indicando come numero minimo
     di occorrenze il valore zero.
     

Asserzioni


     L'asserzione è un test basato su un carattere, che può precedere
     o seguire l'attuale punto di riconoscimento, e non consuma
     alcun carattere. Le semplici asserzioni quali \b, \B, \A, \Z,
     \z, ^ e $ sono state descritte precedentemente. Asserzioni più
     complesse possono essere strutturate come delle sotto-regole.
     Se ne hanno di due tipologie: quelle che "guardano avanti"
     alla posizione attuale nella stringa oggetto del riconoscimento,
     e quelle che "guardano dietro" la posizione attuale.

     Una asserzione definita come sotto-regola esegue il riconoscimento
     nel modo usuale, ma tale riconoscimento non sposta la posizione
     attuale nella stringa. Le asserzioni che "guardano avanti" cominciano
     per "(?=", se sono positive, per "(?!", se sono asserzioni negative.     
     Ad esempio

       \w+(?=;)

     riconosce una parola seguita da ";", ma non include il 
     punto e virgola nel riconoscimento, mentre     

       foo(?!bar)

     identifica qualsiasi occorrenza di "foo" che non sia seguita da
     "bar". Attenzione che il criterio, apparentemente simile,

       (?!foo)bar

     non riconosce alcuna occorrenza di "bar" se questa è preceduta
     da qualsiasi testo che non sia  "foo"; infatti l'espressione 
     riconosce qualsiasi occorrenza di "bar", poiché l'asserzione (?!foo)
     è sempre TRUE quando i tre caratteri successivi sono "bar".
     Pertanto è necessario una asserzione che "guarda" all'indietro 
     per ottenere effetto desiderato.
     
     Le asserzioni che "guardano" indietro positive iniziano con 
     "(?<=", e con "(?<!" le negative. Ad esempio:

       (?<!foo)bar

     riconosce una occorrenza di "bar" che non sia preceduta da 
     "foo". Le asserzioni che "guardano" indietro hanno una limitazione:
     tutte le stringhe che riconoscono devono avere lunghezza fissa.
     Mentre, se si hanno casi alternativi, la limitazione della lunghezza
     fissa non sussiste. Quindi

       (?<=bullock|donkey)

     è una asserzione permessa, ma

       (?<!dogs?|cats?)

     genera un errore durante la fase di compila. Rami alternativi
     con lunghezze di stringa differenti sono permessi solo
     al primo livello dell'asserzione. Questa è da considerarsi una 
     estensione rispetto a Perl 5.005, che richiede a tutte le alternative
     possibili la medesima lunghezza di stringa. Quindi una asserzione
     tipo

       (?<=ab(c|de))

     non è permessa, poiché il suo singolo ramo di primo livello
     può identificare testi di due lunghezze differenti, ma è accettabile
     se riscritta usando due alternative di primo livello:

       (?<=abc|abde)

     L'implementazione di questo tipo di asserzioni consiste, per
     ciascuna alternativa, di uno spostamento all'indietro temporaneo
     per la lunghezza fissa necessaria, e ad un tentativo di 
     riconoscimento del testo. Se non ci sono sufficienti caratteri
     precedenti alla posizione attuale, l'asserzione è destinata a 
     fallire. L'uso accoppiato delle asserzioni che "guardano" indietro
     con sotto-regole a riconoscimento singolo può essere utile
     per identificare la fine dei testi; un esempio è illustrato
     al termine della sezione sulle sotto-regole a riconoscimento 
     singolo.

     Diverse asserzioni (di qualsiasi tipologia) possono essere 
     utilizzate in modo consecutivo. Ad esempio:

       (?<=\d{3})(?<!999)foo

     riconosce "foo" preceduto da tre cifre che non siano "999".
     Occorre rilevare che ciascuna asserzione viene applicata
     singolarmente sul medesimo punto nella stringa oggetto di 
     riconoscimento. Nell'esempio precedente per prima cosa si
     verifica che i tre caratteri precedenti siano cifre, quindi
     che non siamo "999". Questo esempio non identifica il testo
     se "foo" è preceduto da sei caratteri di cui i primi tre siano 
     cifre e i secondi tre non siano "999". In pratica il testo
     "123abcfoo" non viene riconosciuto. Un criterio per riconoscere
     tale stringa può essere:

       (?<=\d{3}...)(?<!999)foo

     In questo caso la prima asserzione controlla i primi sei caratteri
     verificando che i primi tre siano cifre, mentre la seconda
     asserzione verifica che i secondi tre caratteri non siano
     "999".     

     Le asserzioni possono essere annidate in qualsiasi combinazione.
     Il seguente esempio

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

     identifica il testo "baz" se è preceduto da "bar" il quale
     non deve essere preceduto da "foo", mentre    

       (?<=\d{3}(?!999)...)foo

     è un'altro criterio che riconosce "foo" preceduto da tre cifre
     e da tre caratteri che non siano "999".     

     Le asserzioni definite come sotto-regole non catturano parte 
     del testo e non possono essere ripetute (non avrebbe senso
     ripetere il medesimo riconoscimento sul medesimo testo).
     Se una di queste asserzioni contiene una sotto-regola di cattura
     questa viene conteggiata ai fini della numerazione delle regole
     di cattura. Tuttavia il testo viene effettivamente catturato
     solo nelle asserzioni positive, dato che non avrebbe senso farlo
     in quelle negative.

     Le asserzioni possono essere composte fino ad un massimo
     di 200 sotto-regole.
     subpatterns.
     

Sotto-regole a riconoscimento singolo (Once-only subpatterns)


     Con l'indicazione del numero minimo e massimo di ripetizioni,
     il fallimento del riconoscimento della parte successiva del testo
     causa una ripetizione dell'identificazione con un numero di 
     occorrenze diverse per verificare se in questa situazione anche il 
     resto  del testo viene identificato. In alcune situazioni può
     essere utile bloccare questo meccanismo,  per la cambiata
     natura del criterio, oppure per fare fallire la ricerca prima 
     di quando potrebbe accadere, oppure quando l'autore sa che non
     ci sono punti da cui ripartire.

     Consideriamo, ad esempio, il criterio \d+foo applicato alla
     seguente linea

       123456bar

     Dopo avere identificato le 6 cifre ed avere mancato nel riconoscimento
     di "foo", il comportamento normale consiste nel tentare di 
     procedere identificando 5 cifre per l'elemento \d+, quindi
     tentare con 4 e così via, prima di fallire definitivamente.
     Le sotto-regole a riconoscimento singolo permettono di specificare
     che, una volta riconosciuta una porzione della regola, questa
     non debba essere più considerata, in maniera tale da abortire
     immediatamente il riconoscimento se non si ha successo 
     nell'identificare la parte restante del criterio.
     L'espressione per definire questo tipo di sotto-regola richiede
     un'altro tipologia di utilizzo speciale delle parentesi. Infatti
     iniziano con (?> come nell'esempio seguente:

       (?>\d+)bar
   
     Questa tipologia di parentesi "inchioda" la parte di criterio
     una volta che avviene il riconoscimento, e, quindi, un fallimento
     successivo impedisce la ri-elaborazione di questo segmento.
     Tuttavia, occorre notare che gli elementi precedenti a questo
     si comportano in modo normale, e pertanto la ri-elaborazione,
     pur non toccando questo elemento, passa ai precedenti.

     Una descrizione alternativa di questa tipologia di sotto-regola
     potrebbe essere che questo criterio identifica un testo come
     avrebbe fatto un singolo criterio se fosse stato ancorato
     alla posizione corrente.     

     Le sotto-regole a riconoscimento singolo non compiono la cattura
     del testo identificato. I casi semplici illustrati in precedenza
     possono essere considerati come una estremizzazione della
     ripetizione che porta ad inglobare tutto ciò che può. Pertanto,
     da una parte \d+ e \d+? sono sequenze che si adattano a riconoscere
     il numero corretto di cifre affinchè la ricerca abbia successo,
     dall'altra la sequenza (?>\d+) riconosce soltanto una sequenza
     di cifre.

     Ovviamente queste costruzioni possono contenere diverse
     sotto-regole sia complesse, sia annidate.     

     Le sotto-regole a riconoscimento singolo possono essere usate
     congiuntamente alle asserzioni che guardano indietro, per definire
     una regola efficiente per riconoscere la fine della stringa.
     Ad esempio si consideri questo semplice criterio:

       abcd$

     quando viene applicato ad un lungo testo può non avere successo.
     Questo perché il riconoscimento procede da sinistra verso destra,
     quindi PCRE prima cerca la "a", e poi cerca di riconoscere la
     parte restante del criterio. Se si modifica il criterio nel 
     seguente modo

       ^.*abcd$

     allora la sequenza iniziale .* in prima battuta identificherà
     tutto il testo, ma quando fallisce (poiché non vi sono più "a"),
     la ricerca tornerà indietro di uno (quindi tutto il testo tranne
     l'ultimo carattere), quindi, se continua non esserci la "a", si
     torna indietro di due, e così via. Continuando a tornare indietro
     alla ricerca della "a" si percorre tutto il testo da destra a
     sinistra, senza ottenere nulla di valido. Tuttavia se si 
     riscrive il criterio come:

       ^(?>.*)(?<=abcd)

     non si attiva più lo scorrimento verso sinistra per .* , ma viene
     costretto a riconoscere tutto il testo (esito del primo tentativo).
     La asserzione successiva, esegue una verifica sulle ultime 4 
     lettere.Se fallisce, ciò avviene immediatamente, provocando 
     un impatto sensibile nei tempi di elaborazione con testi molto
     lunghi.

     Quando un criterio di riconoscimento contiene un elemento
     ripetuto senza limite all'interno di una sotto-regola che
     anch'essa possa ripetuta illimitatamente, l'uso delle sotto-regole
     a riconoscimento singolo è l'unico mezzo per evitare che 
     certi mancati riconoscimenti richiedano molto tempo per essere
     rilevati. Ad esempio il criterio   

       (\D+|<\d+>)*[!?]

      riconosce un numero indefinito di frammenti di testo contenenti
      a loro volta numeri o caratteri non numerici racchiusi tra <>,
      seguiti dai caratteri ! o ?. Quando il riconoscimento ha successo
      l'esecuzione è rapida, ma quando viene applicato al testo   
  
       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

      richiede molto tempo prima di evidenziare l'errore. Questo
      accade perché la stringa può essere suddivisa tra i due elementi
      ripetuti in un elevato numero di modi che debbono essere
      verificati. Nell'esempio si usa [!?] piuttosto che un singolo
      carattere alla fine, questo perché sia Perl sia PCRE hanno una 
      ottimizzazione che permette un veloce riconoscimento dell'errore
      se si usa un solo carattere. Infatti memorizzano l'ultimo
      carattere singolo richiesto per un riconoscimento, e, se non
      lo trovano nel testo, falliscono subito. Se il criterio viene
      modificato in 

       ((?>\D+)|<\d+>)*[!?]

     le sequenze di caratteri non numerici non possono essere 
     interrotte e pertanto il mancato riconoscimento viene rilevato
     più velocemente.     
     

Sotto-regole condizionali (Conditional subpatterns)


     E' possibile forzare il processo di riconoscimento a obbedire
     alle sotto-regole in modo condizionato, oppure a scegliere 
     tra due alternative in base al risultato di una asserzione,
     o piuttosto se la sotto-regola di cattura precedente ha 
     riconosciuto il proprio testo. I due metodi possibili per 
     esprimere una sotto-regola condizionale sono:

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

     Se la condizione è soddisfatta, si usa la regola indicata in
     yes-pattern, altrimenti si applica il no-pattern (qualora sia
     specificato). Se nella sotto-regola vi sono più di due
     alternative, PCRE segnala un errore in fase di compila.  

     Vi sono due tipi di condizioni. Se il testo tra le parentesi
     consiste in una sequenza di cifre, allora la condizione è 
     soddisfatta se la sotto-regola di cattura di quel numero 
     è stata precedentemente riconosciuta. Si consideri il seguente
     criterio contenente degli spazi non significativi per renderlo
     più leggibile (si assuma che sia attiva l'opzione PCRE_EXTENDED)
     e lo si divida in tre parti per praticità di discussione:

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

     La prima parte riconosce una parentesi aperta opzionale, e,
     se è presente, indica quello come primo segmento di stringa
     catturato. La seconda parte riconosce uno o più caratteri che
     non siano parentesi. Infine la terza parte è una sotto-regola
     condizionale che verifica se la prima parentesi è stata identifica
     o meno. Se accade, come nel caso in cui il testo inizi con una
     parentesi aperta, la condizione è TRUE, e quindi viene eseguito 
     il ramo yes-pattern, richiedendo, conseguentemente, la parentesi chiusa.
     Diversamente, poiché non è specificato ramo no-pattern, non si 
     esegue nessun altro riconoscimento. In altre parole questo criterio
     identifica un testo che possa essere racchiuso tra parentesi
     opzionali.

     Se la condizione non è una sequenza di cifre, deve essere
     una asserzione. Questa può essere sia una asserzione che
     guarda avanti, sia una asserzione cha guarda indietro, sia positiva
     sia negativa. Si consideri il seguente criterio, ancora una volta
     contenente spazi non significativi, e con due alternative nella
     seconda linea:

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

     La condizione è una asserzione che guarda avanti positiva, la quale 
     identifica una sequenza opzionale di caratteri non alfabetici
     seguiti da una lettera. In altre parole, si testa la presenza
     di almeno una lettera nel testo. Se la lettera viene trovata
     si applica il primo criterio per il riconoscimento del testo,
     altrimenti viene applicato il secondo criterio. Questo criterio 
     riconosce  stringhe in due formati dd-aaa-dd oppure dd-dd-dd,
     dove aaa sono lettere e dd sono numeri.
     

Commenti


     La sequenza (?# indica l'inizio di un commento che si conclude
     con la successiva parentesi chiusa. Parentesi annidate non sono
     permesse. I caratteri che fanno parte di un commento non giocano
     alcun ruolo nella fase di riconoscimento.

     Se viene attivata l'opzione PCRE_EXTENDED,
     un carattere # privo della sequenza di escape (\) all'esterno
     di una classe di caratteri apre un commento che continua fino
     al carattere di "a capo".
     

Criteri ricorsivi


     Si consideri il caso in cui si debba riconoscere una stringa tra parentesi,
     si supponga inoltre di dovere ammettere un numero arbitrario
     di parentesi annidate. Senza l'uso della ricorsione, il miglior
     metodo consiste nel preparare un criterio che identifichi un 
     numero finito di parentesi annidate. Però, in questo modo non si 
     gestisce un numero arbitrario si parentesi annidate. Nella
     versione 5.6 di Perl è stata introdotta, a livello sperimentale,
     la possibilità per i criteri di riconoscimento di essere ricorsivi.
     Allo scopo è stata definita la sequenza speciale (?R). Il criterio
     illustrato di seguito risolve il problema delle parentesi 
     (si assume che l'opzione PCRE_EXTENDED
     sia attivata in modo da ignorare gli spazi):

       \( ( (?>[^()]+) | (?R) )* \)

     In principio si identifica la parentesi di apertura. Quindi 
     si cerca un numero indefinito di stringhe che possano essere
     composte da caratteri che non siano parentesi, oppure che
     siano riconosciute ricorsivamente dal criterio (ad esempio una
     stringa correttamente tra parentesi). Infine si cerca la
     parentesi di chiusura.

     In questo particolare esempio si hanno arbitrarie ripetizioni
     annidate, e quindi l'uso delle sotto-regole a riconoscimento singolo
     per il riconoscimento della stringa priva di parentesi è particolarmente
     utile se il criterio viene applicato ad un testo non riconoscibile.
     Ad esempio, applicando il criterio a

       (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()

     si ottiene un esito di mancato riconoscimento rapidamente. Se,
     al contrario, non si fosse usato il criterio a riconoscimento 
     singolo, sarebbe occorso molto tempo per avere un esito dato
     che vi sono moltissimi  modi in cui i caratteri di ripetizione + e *
     possono essere applicati al testo, richiedendo, pertanto,
     la verifica di tutte le combinazioni prima di fornire l'esito
     negativo.

     Il valori restituiti da una sotto-regola di cattura sono quelli
     ottenuti dal livello di ricorsione più esterno. Se il criterio
     illustrato in precedenza venisse applicato al testo

       (ab(cd)ef)

     Il valore ottenuto sarebbe "ef", che rappresenta l'ultimo 
     valore catturato al livello più alto. Se si aggiungono altre
     parentesi al criterio, ottenendo 

       \( ( ( (?>[^()]+) | (?R) )* ) \)
          ^                        ^
          ^                        ^ allora il testo ottenuto sarebbe
     "ab(cd)ef", cioè il valore delle parentesi di livello più alto.
     Se nel criterio vi sono più di 15 sotto-regole di cattura,
     PCRE ha necessità di ottenere maggiore memoria per archiviare
     le informazioni durante la ricorsione. Questa memoria è ottenuta
     utilizzando pcre_malloc, al termine verrà liberata con pcre_free.
     Se non può essere ottenuta ulteriore memoria, si ha il salvataggio
     delle informazioni dei primi 15 testi catturati, dato che non vi è modo
     di restituire un messaggio di memoria insufficiente dalla 
     ricorsione.
     

Performances


     Certi elementi utilizzati per i criteri di riconoscimento sono più 
     efficienti di altri. E' più efficiente usare le classi di caratteri come
     [aeiou] piuttosto che un gruppo di alternative come (a|e|i|o|u).
     In generale la costruzione più semplice per ottenere un dato 
     scopo è la più efficiente. Nel libro di Jeffrey Friedl sono 
     illustrate varie tecniche sull'ottimizzazione delle espressioni
     regolari.

     Quando un criterio comincia con .* ed è attiva l'opzione PCRE_DOTALL, il
     criterio è implicitamente ancorato da PCRE, dato che può rico-
     noscere solo l'inizio della stringa. Tuttavia, se non è attivo 
     PCRE_DOTALL, PCRE non può 
     fare questa ottimizzazione, perché il meta-carattere .  non ri-
     conosce più il carattere di "a capo", e quindi se la stringa 
     contiene dei caratteri di "a capo", il riconoscimento può par-
     tire dal carattere immediatamente successivo ad uno di questi 
     e non dall'inizio. Ad esempio il criterio

       (.*) second

     può eseguire un riconoscimento nel testo "first\nand second"
     (dove \n indica il carattere "a capo") ottenendo "and" come
     prima stringa catturata. perché ciò accada è necessario che 
     PCRE possa iniziare il riconoscimento dopo ogni "a capo".

     Se si deve usare un simile criterio in stringhe che non conten-
     gono caratteri di "a capo", le performance migliori si possono 
     ottenere abilitando PCRE_DOTALL,
     oppure iniziando il criterio con ^.* in modo da richiedere un 
     ancoraggio esplicito. Così si risparmia a PCRE di scandirsi il 
     testo alla ricerca di un "a capo" da cui ripartire per la ri-
     cerca.

     Occorre prestare attenzione ai criteri che contengono ripeti-
     zioni indefinite annidate. Possono richiedere molto tempo se 
     applicati a stringhe non riconoscibili. Si consideri il fram-
     mento

       (a+)*

     Questo può riconoscere "aaaa" in 33 modi differenti, e questo
     numero può crescere molto rapidamente se la stringa da ricono-
     scere è più lunga. (Il carattere di ripetizione * può eseguire 
     riconoscimenti per 0,1,2,3 o 4 ripetizioni, e per ciascuna di 
     esse, tranne lo 0, il carattere di ripetizione + può esegui-
     re riconoscimenti per diversi numeri di volte). Quindi se la 
     parte successiva del criterio è tale da non permettere il com-
     pletamento del riconoscimento, PCRE, per principio, ugualmente
     tenta tutte le possibili variazioni, richiedendo diverso tempo.

     Una ottimizzazione riesce a catturare qualche caso semplice
     come in 

       (a+)*b

      dove si indica che seguirà un  carattere alfanumerico. PCRE,
      prima di imbarcarsi nella procedura standard di riconoscimen-
      to, verifica se nel testo vi è la  lettera "b", e  se non c'è 
      restituisce immediatamente un esito negativo. Tuttavia se non 
      viene indicata una lettera seguente questa ottimizzazione non
      può essere utilizzata. Se ne può notare la differenza analiz-
      zando il comportamento del criterio

       (a+)*\d

     rispetto al precedente. Il primo, utilizzato con  una  stringa
     composta da "a", fallisce immediatamente, l'ultimo richiede un
     tempo  apprezzabile, soprattutto  se  applicato a stringhe con 
     più di 20 caratteri.