È possibile! Si può avere ogni livello di contenuti utilizzando un ricorsiva espressione regolare:
$data = <<<LOD
{{START1}}
aaaaa
{{START2}}
bbbbb
{{START3}}
ccccc
{{START4}}
ddddd
{{END4}}
{{END3}}
{{END2}}
{{END1}}
LOD;
$pattern = '~(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))~';
preg_match_all ($pattern, $data, $matches);
print_r($matches);
spiegazioni:
parte: ({{START\d+}}(?>[^{]++|(?1))*{{END\d+}})
Questa parte del modello descrive una struttura annidata con {{START#}}
e {{END#}}
( # open the first capturing group
{{START\d+}}
(?> # open an atomic group (= backtracks forbidden)
[^{]++ # all that is not a { one or more times (possessive)
| # OR
(?1) # refer to the first capturing group itself
) # close the atomic group
{END\d+}} #
) # close the first capturing group
Ora il problema è che non è possibile acquisire tutto il livello con questa parte solo, perché tutti i caratteri della stringa sono consumati dal modello. In altre parole, non è possibile abbinare parti sovrapposte della stringa.
Il problema è quello di avvolgere tutta questa parte all'interno di un'asserzione a lunghezza zero, che non consuma personaggi come un lookahead (?=...)
, risultato:
(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))
Ciò corrisponderà a tutti i livelli.
fonte
2013-06-22 04:56:16
Non può essere fatto con la maggior parte dei regex, anche se ci sono trucchi, oltre al mio ken, che lo rendono possibile in linguaggi come Perl. Leggi il lemma del pompaggio per scoprire perché non puoi farlo. – siride
suppongo che la tua formattazione sia una specie di input. Se hai spiegato un po 'di più forse potrebbe essere suggerito un approccio alternativo. –
Sembra che tu stia cercando di analizzare qualcosa ... [Se qualcosa è così complesso come l'HTML (mi sembra così), farlo con espressioni regex è una cattiva idea.] (Http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454 # 1732454) – michaelb958