Harry: "Intelligente" RegExps

Beitrag lesen

Moinmoin !

Nun brüte ich schon seit einigen Tagen über einem Problem, auf dessen ("schöne") Lösung ich einfach nicht komme. Das Problem besteht genauer gesagt in der Formulierung eines regulären Ausdrucks.
Es geht darum, in einem von einem Benutzer eingegebenen Text bestimmte markierte Teile durch HTML zu ersetzen (ähnlich wie hier im Forum <blabla>.

Beispieltext:

Dies ist ein Text mit [fett:fetter Schrift], der hier weitergeht.

Nun kann ich ja problemlos die entsprechende Stelle durch HTML-Code ersetzen (ich verwende hier PHP, aber das ist ja eigentlich egal, es geht nur um den regulären Ausdruck):

preg_replace("/[fett\s?:\s?(.*)\s?]/i", "<b>\1</b>", $text);

Das funktioniert soweit ganz gut, kritisch wird es nur, wenn solch eine Konstruktion vorkommt:

Dies ist ein [kursiv:kursiver Text, der hier [fett:fett geschrieben ist] und hier kursiv] bzw. normal weitergeht.

Wenn ich nun zuerst den fetten und dann den kursiven Teil ersetze, ist auch alles in Ordnung. Blöd wird die Sache aber, wenn zuerst versucht wird, den kursiven Teil zu ersetzen und dann den fetten.

Dann schaut das Ergebnis nämlich so aus:

Die ist ein <i>kursiver Text, der hier <b>fett geschrieben ist</i> und hier kursiv</b> bzw. normal weitergeht.

Obenstehendes Ergebnis ist aus Sicht des von mir verwendeten Ausdruckes ja durchaus korrekt. Schließlich heißt es ja, daß an der nächsten schliessenden eckigen Klammer der kursive Text zu Ende sei. Das ist aber nicht der Fall, da bei der ersten schliessenden eckigen Klammer ja eigentlich erst der der fette Text zu Ende ist.

Jetzt ist die Frage: Wie bringe ich es dem Ausdruck bei, daß er - wenn sich in seinem "Einzugsbereich" weitere X öffnende eckige Klammern befinden er gefälligst auch erst bei der X. schliessenden Klammer Schluß machen soll ?

Von mir aus kann man die ganze Sache auch gerne "anders" lösen, also nicht unbedingt mit einem RegExp. Ich würde jedoch gerne bei der aufgezeigten Struktur bleiben, d.h. ich möchte eigentlich nicht auf Lösungen wie [fett]Text[/fett] umsteigen.

Mein bisherige Lösung schaut so aus, daß ich den Text mit Hilfe mehrerer Explodes bzw. preg_split in seine Einzelteile zerlege und diese in ein n-dimensionales Array (je nach Verschachtelung) einlese, und dann alles entsprechend ersetze (ok, ich hab die Lösung noch nicht ausprobiert, bin mir aber ziemlich sicher, daß sie funktionieren würde) und je nach bedarf den Original-String aus dem Array wieder zusammensetze. Das wär halt nur ein ziemlicher Aufwand und ist für meine Begriffe auch nicht besonders elegant gelöst.

Wenn also jemand Vorschläge hat, wie man die Sache "sauber" lösen könnte oder - noch besser - gar einen passenden RegExp auf Lager hat, immer her damit :)

Ich hatte mir auch schon Gedanken gemacht, die Reihenfolge der vorzunehmenden Ersetzungen von innen nach außen festzustellen und dann die Ersetzungen entsprechend vorzunehmen, bin aber auf keine vernünftige Idee gekommen, wie man das lösen könnte, da die Struktur im Endeffekt beliebig komplex werden kann (es soll die Möglichkeit geben, außer [fett:], [kursiv:] und [link(http://irgendwas.com):] noch beliebig viele andere Formatierungen vornehmen zu können, die (prinzipiell) beliebig verschachtelt werden können) ...

Vielen Dank schonmal.

In gespannter Erwartung,

Harry