Rolf b: preg_replace Problem

Beitrag lesen

Würde mich auch interessieren, welche fertige Library dafür geeignet ist. Wenn man es ohne Regex mit der Hand programmiert, wird es sicherlich fixer, aber auf jeden Fall ist der Code dann länger.

Deine Regex funktioniert aber schlecht. Sollte

TEXTTEXT {{ ZITAT 1 { ZITAT FORTSETZUNG }} ENDE TEXT

nicht

TEXTTEXT <q> ZITAT 1 { ZITAT FORTSETZUNG </q> ENDE TEXT

ergeben? Tut es aber nicht.

Ich habe es mal mit einer lookahead-Assertion versucht. Das Pattern matcht zuerst ein {{ und macht die Assertion, dass darauf kein weiteres {{ folgt. Dann matcht es beliebige Zeichen, aber non-greedy, und ein }}. Der non-greedy Match sorgt dafür, dass .* bei einem geschachtelten Zitat das innere }} nicht einschließt.

Das ganze legst Du in eine Schleife und machst es so lange, wie etwas ersetzt wird. Die Spielerei mit $i soll nur anzeigen, in welcher Reihenfolge er die Zitate ersetzt. Das musst Du natürlich für den realen Einsatz entfernen.

$text = "TEXTTEXT {{ ZITAT 1 {{ ZITAT 2 }} Z1 }} {{ ENDE }} TEXT";

$i=1;
while (true) {
   $textNeu = preg_replace("//{{(?!.*{{)(.*?)}}/i","<q_$i>$1</q_$i>",$text);
   if ($text === $textNeu) break;
   $text = $textNeu;
   $i++;
}
echo $text;

Eine Lösung ohne Regex wäre wohl ein handgemachter Parser, der von links nach rechts durchgeht und einen Quote-Stack bildet, oder die Nutzung einer PHP Library, die ich nicht kenne.

Rolf