Reguläre Ausdrücke: Suchmuster funktioniert nicht
sprite
- php
0 MudGuard
0 Texter mit x0 sprite0 MudGuard
0 Tom0 MudGuard
0 Texter mit x0 Tom0 Texter mit x0 Tom
Hallo,
ich habe mehrere Dateien, die von verschiedenen Autoren stammen können.
Diese sollen zentral zusammengeführt werden, wofür ich von jedem Autor
Diese Informationen sollen in den Dateien transportiert werden, bei denen es sich um Smarty-Templates handelt. Sinnvollerweise als Smarty-Kommentare, damit die Templates trotz der enthaltenen Infos weiter ihren Dienst verrichten.
Verpackt sind die Informationen wie folgt:
{*version=2.0*}
{*description=das ist eine beschreibung*}
{*key=stichwort eins*}
{*key=stichwort zwei*}
{*key=stichwort drei*}
Ausgelesen werden sollen sie per PHP preg_match(_all):
/** Nach Templateinformationen suchen */
$pattern = "/\{\*description=(.+)\*\}/i";
if(0 != preg_match($pattern, $file, $matches)) { // etw. gefunden
$description = $matches[1];
} else {$error = true;}
/** Nach Stichworten suchen */
$pattern = "/\{\*key=(.+)\*\}/i";
if(0 != preg_match_all($pattern, $file, $matches, PREG_PATTERN_ORDER)) { // Stichworte gefunden
$infos = $matches[1];
} else {$error = true;}
Beide Suchmuster bringen auch das gewünschte Ergebnis:
das ist eine beschreibung
Array ( [0] => stichwort eins [1] => stichwort zwei [2] => stichwort drei )
Jedoch könnte eine Beschreibung mehrzeilig sein. Ein
{*description=das is
t eine beschreibung*}
im Template lässt die Funktion preg_match nichts mehr finden.
Eine Abänderung des entsprechenden Suchmusters auf
/^\{\*description=(.+)\*\}$/i
bringt auch nicht den gewünschten Effekt.
Kann mir jemand einen Denkanstoß geben, wie ich das Muster ändern muss, damit der gewünschte Effekt eintritt?
Vielen Dank (:
Hi,
$pattern = "/{\description=(.+)\}/i";
Jedoch könnte eine Beschreibung mehrzeilig sein. Ein
Solange das s-flag nicht gesetzt ist, matcht der . keine Zeilenumbrüche.
cu,
Andreas
Solange das s-flag nicht gesetzt ist, matcht der . keine Zeilenumbrüche.
Falls man das noch nicht kennt und man danach suchen muß, ist s-Modifier der bessere Begriff, denke ich.
Solange das s-flag nicht gesetzt ist, matcht der . keine Zeilenumbrüche.
Falls man das noch nicht kennt und man danach suchen muß, ist s-Modifier der bessere Begriff, denke ich.
Ich habe die Modifier hier nachgeschlagen und erhalte mit folgendem Suchmuster
/\{\*description=(.+)\*\}/is
dieses Ergebnis:
das is t eine beschreibung*} {*key=stichwort eins*} {*key=stichwort zwei*} {*key=stichwort drei
Das sagt mir doch, dass das Suchmuster jetzt durchaus für mehrere Zeilen gilt, aber das die Suche nicht beim ersten schließenden
*}
, sondern beim letzten vorkommenden beendet wird.
Wieso?
Weil (.+) nunmal für alle Zeichen gilt, welche * und } einschließen.
Wie behebe ich das?
Für den Beschreibungstext alle Zeichen bis auf * und } erlauben.
Bedeutet: Für erlaubte Zeichen einfach *} negieren.
Was mich zu dem Suchmuster
/\{\*description=([^\*\}]+)\*\}/is
bringt.
Welches funktioniert (:
Danke für eure Antworten.
Hi,
Das sagt mir doch, dass das Suchmuster jetzt durchaus für mehrere Zeilen gilt, aber das die Suche nicht beim ersten schließenden
*}
, sondern beim letzten vorkommenden beendet wird.Wieso?
Weil (.+) nunmal für alle Zeichen gilt, welche * und } einschließen.
Weil Du nicht berücksichtigt hast, daß + und * ohne ? gierig (greedy) sind.
cu,
Andreas
Hello,
Wieso?
Weil (.+) nunmal für alle Zeichen gilt, welche * und } einschließen.Weil Du nicht berücksichtigt hast, daß + und * ohne ? gierig (greedy) sind.
...was mich jetzt hier mal zu einer Frage bringt, die ich schon immer mal stellen wollte:
Wie es sich auswirkt, wenn man die Gefräßigkeit herabsetzt, ist mir klar. Aber woher weiß die Engine dann, wann sie aufhören muss zu fressen? Wie läuft dieser Algorithmus ab? Wie oft darf das Muster, dass nach einem ungreedy geschalteten Quantifier noch kommt, im Gesamttext noch vorkommen?
A(.+?)bauen
Hält der Algorithmus nun beim ersten 'bauen', dass auf ein 'A' zuzügl. mindestens einem Folgezeichen folgt an?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi,
...was mich jetzt hier mal zu einer Frage bringt, die ich schon immer mal stellen wollte:
Wie es sich auswirkt, wenn man die Gefräßigkeit herabsetzt, ist mir klar. Aber woher weiß die Engine dann, wann sie aufhören muss zu fressen? Wie läuft dieser Algorithmus ab? Wie oft darf das Muster, dass nach einem ungreedy geschalteten Quantifier noch kommt, im Gesamttext noch vorkommen?
Buchempfehlung: Jeffrey E. Friedl, Mastering Regular Expressions (3rd edition), O'Reilly-Verlag
Da ist das alles sehr genau erklärt, viel besser als ich das könnte.
Ist leider nicht billig, aber preiswert.
cu,
Andreas
Aber woher weiß die Engine dann, wann sie aufhören muss zu fressen? Wie läuft dieser Algorithmus ab? Wie oft darf das Muster, dass nach einem ungreedy geschalteten Quantifier noch kommt, im Gesamttext noch vorkommen?
Ist das von ungreedy nicht unabhängig? Im Fall greedy passen alle "bauen" vor dem letzten "bauen" in das (.+?) also steckt er die da auch rein.
A(.+?)bauen
Hält der Algorithmus nun beim ersten 'bauen', dass auf ein 'A' zuzügl. mindestens einem Folgezeichen folgt an?
Ich glaube die Antwort ist ganz einfach, es paßt auf den kürzesten möglichen Ausdruck auf den es paßt, also ja.
Ich bin mir aber nicht sicher, ob das war was Du wissen wolltest.
Hello,
Ich bin mir aber nicht sicher, ob das war was Du wissen wolltest.
Im Prinzip schon.
Nur habe ich es gemäß dieser (Selbst-)Erläuterung schon öfter mal erlebt, dass es nicht so lief, wie ich dachte. Und da wäre es doch schön, den Algorithmus genauer kennenzulernen. Sollte irgendwann ein Kunde mal wieder bezahlen, werde ich das Geld fürs empfohlene Buch abzweigen :-)
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Nur habe ich es gemäß dieser (Selbst-)Erläuterung schon öfter mal erlebt, dass es nicht so lief, wie ich dachte.
Hast Du ein Beispiel zur Hand? Sonst das nächste mal, würde mich interessieren.
Hello,
Nur habe ich es gemäß dieser (Selbst-)Erläuterung schon öfter mal erlebt, dass es nicht so lief, wie ich dachte.
Hast Du ein Beispiel zur Hand? Sonst das nächste mal, würde mich interessieren.
Ich bin mir jetzt nicht sicher, aber ich glaube, ich hatte letztens auch so ein Problem hier gepostet. Es lag dann nur am Unterschied zwischen (.*?) und (.+?) im größeren Zusammenhang verwendet. Da hatte ich vergessen zu fordern, dass ich aber etwas zurück haben wollte...
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg