Sintassi delle regex PCRE
PHP Manual

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 CRE_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.

(?1), (?2) e così via possono pure essere usati per sottoregole ricorsive. È anche possibile usare sottoregole con nome: (?P>name) oppure (?P&name).

Se la sintassi di un riferimento a sottoregola (identificata per numero o per nome) è usata al di fuori delle parentesi a cui si riferisce, si comporta come una funzione di un linguaggio di programmazione. Un esempio precedente mostrava come la regola (sens|respons)e and \1ibility trova "sense and sensibility" e "response and responsibility", ma non "sense and responsibility". Se si usa invece la regola (sens|respons)e and (?1)ibility, questa identifica anche "sense and responsibility", come pure le altre due stringhe. Questi riferimenti devono, comunque, seguire le sottoregole a cui si riferiscono.

La lunghezza massima di una stringa corrisponde al pìù grande numero positivo ammesso per una variabile integer. D'altra parte, PCRE usa la ricorsione per gestire le sottoregole e le ripetizioni indefinite. Questo significa che lo spazio di stack disponibile può limitare la dimensione di una stringa che può essere processata da determinate regole.


Sintassi delle regex PCRE
PHP Manual