Reguläre Ausdrücke - Expert needed!

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Reguläre Ausdrücke - Expert needed!
“Was ist das denn schon wieder??” - Dann bist du hier glaub ich falsch, sorry.

Du bist noch da? OK, ich hab da nämlich gewisse Schwierigkeiten mit diesen Dingern. Nachdem ich jetzt mehrere Stunden mit diesen blöden regulären Ausdrücken verbracht hab, funktioniert mein Programm immer noch nicht. Es geht ganz konkret um eine äußert komplexe Textersetzung in PHP mithilfe der Funktion preg_replace(). Alles was ich dazu in der PHP-Dokumentation gefunden habe, hat mir entweder nicht geholfen oder ich hab’s nicht richtig verstanden… Gerade die Abschnitte mit Bedingungen und Back-References.

Ich hab dich noch nicht verschreckt? Wirklich?? Toll! Ich würd mich auf jeden Fall freuen, wenn du dich mit mir in Verbindung setzen könntest, dann kann ich dir den Programmcode mal mailen (über 700 Zeilen, zuviel für hier). So langsam verliere ich den Glauben daran, dass meine Anforderungen überhaupt irgendwie realisierbar sind :frowning:

Ach ja, falls du jemanden kennst, [der jemanden kennt, […]] der sich mit sowas auskennt, gilt derjenige hiermit automatisch als auch gefragt! Danke.


OK, ich habe das Problem jetzt auf ein Testprogramm reduziert, das gut auf eine Seite passt.

Und kurz zur Info: Es geht darum, verschachtelte BBCode-Tags in HTML zu übersetzen. Richtige Beispiele kann ich hier nicht angeben, die würden sofort übersetzt werden! Aber so in der Art sieht es aus:

anfang (b)bold(/b) normal (b)bold2(/b) normal2 (b)bold3(/b) ende anfang (b)bold (b)bold2(/b) bold3(/b) ende anfang (b)bold1 (b)boldbold1(/b) bold1(/b) mitte (b)bold2 (b)boldbold2(/b) bold2(/b) ende

Also so gesehen nichts schwieriges. Nur das dem PC beizubringen - …


So komplex sieht das doch gar nicht aus. Ich denke um die Verschachtelung musst du dir keine Sorgen machen; das wird ja in HTML genauso gehandhabt. Wie wärs denn mit:
tr/(b)//gis
tr/(/b)/</b>/gis

Das wäre jedenfalls die Perl-Syntax, aber glaube in PHP ist es recht ähnlich. Vielleicht musst du die Modifier (ich würde mal “gis” vorschlagen) als einzelnen Parameter angeben.
Und darauf achten, dass alle Steuerzeichen (d.h. Klammern, Slashes) escaped werden!


Ja, schon gut, genau das macht ja die aktuelle Version dieser Übersetzung. Nur hätte ich schon gerne geprüft, ob denn das schließende Tag auch da ist, sonst lassen wir’s lieber bleiben mit der Übersetzung.

Und da liegt mein Problem: Wenn ich nur nach den einfachen Tags suche (so: “(b)” irgendwas “(/b)”) dann fallen alle Verschachtelungen (siehe oben) gleich durch. Wenn ich vorher genau danach suche (so: “(b)” … “(b)” … “(/b)” … “(/b)”), dann bekomme ich das Problem, dass mir das Teil bei nacheinander vorkommenden, nichtverschachtelten Tags (1. Zeile des Beispiels) das 1. öffnende Tag findet, dann das 2. öffnende Tag auch - allerdings ist da noch ein schließendes dazwischen, was dabei völlig untergeht. Das Ergebnis ist dementsprechend hässlich. Ich habe jetzt auf verschiedene Weisen versucht, eine Art Bedingungen in die reg. Ausdrücke einzufügen, sodass dieser Ausdruck (an dieser Stelle) fehlschlägt, sobald in dem ersten “irgendwas” ein schließendes Tag drinsteht; ohne Erfolg… Deshalb dieser Thread.


Geb dem Prob halt so aus dem Weg, dass du einen kleinen Algorithmus schreibt, der die Open- und Close-Tags jeweils durchzählt, vergleicht und ne Fehlermeldung ausgibt, wenn deren Anzahl nicht gleich ist. Dann braucht dich die Verschachtelung nicht zu jucken…


Suche doch einfach nach Blöcken in der Form
/(b)(.*)(/b)/is
(Achtung: Greedy Matching anlassen), und wenn du einen solchen findest, dann such im Inhalt (d.h. was zwischen den Tags steht) nochmal danach und wiederhol das ganze Spiel solange, bis nix mehr gefunden wird.


Aah, einer der sich auskennt…
kannst du mir vielleicht so auf die Schnelle mal verraten, was es mit diesem “(un)greedy matching” auf sich hat? Hab das in letzter Zeit schon öfters gehört, aber kein Plan, was es bedeutet.

Dein Vorschlag hört sich zuerst mal ganz gut an, wenn ich das jetzt noch versteh, könnte ich es vielleicht auch glauben :slight_smile:

Anmerkung:
Mehr Infos zu diesem Problem sammel ich auch bei PhpBuilder.
Eine erste Demoversion meines Vorhabens befindet sich unter http://software.unclassified.de/abbc.


Zum Greedy Matching:
Nehmen wir mal an du hast folgenden Text:
asdfblablafoo barabcdef

Wenn du jetzt nach .* suchst, erhältst du:
blablafoo barabcdef

Standardmäßig wird immer möglichst viel zurückgeliefert (“gierig”).

Das Greedy Matching kannst du unterdrücken, wenn du nach dem Quantifier noch ein Fragezeichen schreibst.
.*?
ergibt:
blablafoo bar


Achso, ja, das kenn ich schon. Nur im PhpBuilder-Forum hat mir einer erklärt, dass der Nachteil an RegExps ist, dass sie “nicht zählen” können. Und ich glaub sowas bräuchte ich für die Lösung des Problems…

Naja, hab mir jetzt ein Konzept ausgedacht, mit dem ich in einem “ersten Durchlauf” selbst nach den Tags suche und nur noch die Ersetzung der passenden Paare mit RegExps mache. Mal sehen wie das so läuft.

Ich hab aber schon festgestellt, dass sich damit wohl noch niemand so recht auseinandergesetzt hat… In jedem Forum gibt es andere Schwierigkeiten mit der Anzeige von verschachtelten oder falsch verwendeten Tags… Sowas wollte ich eigentlich vermeiden :slight_smile:


Hab das Problem jetzt anders gelöst… siehe PhpBuilder-Thread