preg_match_all() -> Schleife im Templatesystem

Fragen zu allen Themen rund ums Programmieren außerhalb von phpBB können hier gestellt werden - auch zu anderen Programmiersprachen oder Software wie Webservern und Editoren.
Antworten
Pingu625

preg_match_all() -> Schleife im Templatesystem

Beitrag von Pingu625 »

Hallo,

also ich habe mir für meine Webseite ein Templatesystem gebastelt, dass schon ziemlich viel kann, aber bei den Schleifen bleibe ich stecken. :oops:

Und zwar möchte ich nun den Code herausfinden, der zwischen <!-- BEGIN xy --> und <!-- END xy --> steht:

Dies habe ich zuerst so versucht:

Code: Alles auswählen

preg_match_all('|<!-- BEGIN '.$name.' -->(*.*)<!-- END '.$name.' -->|U', $this->content, $blocks, PREG_SET_ORDER);
Danach so (nur der erste Parameter angegeben):

Code: Alles auswählen

#<!-- BEGIN '.$name.' --> (.*) <!-- END '.$name.' -->#
Aber keines der beiden, hat mir die Ausgabe bereitet.

xy steckt also wie man sieht in der Variable $name.

Es wäre sehr nett, wenn mir einer von euch auf die Sprünge helfen könnte ;)

Pingu
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Beitrag von gn#36 »

Das Problem an der Funktion sind im Prinzip die Verschachtelungen. Ich habe mich da auch schon mal sehr intensiv mit beschäftigt und habe mit preg_match_all oder ähnlichen Funktionen keine Möglichkeit gefunden die Verschachtelung korrekt zu erkennen.
Wie du vorgehen musst hängt ganz davon ab was du genau willst. Wenn du (um bei deinem Beispiel zu bleiben) xy genau kennst (also genau weißt wonach du suchst) und es nur ein mal vorkommt kannst du ja einfach

Code: Alles auswählen

$inhalt = preg_replace('#(.*?)<!-- BEGIN '.$wert_von_xy .' -->(.*?)<!-- END '.$wert_von_xy .' -->(.*?)#s','\\2', $alles_zusammen);
verwenden.

Ich würde allerdings eine Suche mit PREG_PATTERN_ORDER bevorzugen:

Code: Alles auswählen

preg_match_all('|<!-- BEGIN '.$name.' -->(.*?)<!-- END '.$name.' -->|s', $this->content, $blocks, PREG_PATTERN_ORDER);
Die Inhalte findest du dann in $blocks[1][$i]

Dein Beispiel enthält auch einen Fehler: *.* sucht nach * und dann beliebigen Zeichen, dein zweites Beispiel ist besser (außer dass die Leerzeichen eventuell stören könnten), allerdings ist dieses Beispiel "gierig", d.h. wenn du eine Konstruktion wie diese hast:

Code: Alles auswählen

<!-- BEGIN hallo --> Testtext 1 <!-- END hallo -->
<!-- BEGIN hallo --> Testtext 2 <!-- END hallo -->
Dann wird dir dein Muster als Inhalt das hier ausspucken:

Code: Alles auswählen

 Testtext 1 <!-- END hallo -->
<!-- BEGIN hallo --> Testtext 2 
Mein Vorgehen war:
  • per preg_match_all erst mal alle Blöcke erkennen (Anfang und Ende)
  • Das ganze dann durch php-Code ersetzen den man ja dann ausführen kann.
Zuletzt geändert von gn#36 am 01.07.2007 02:38, insgesamt 1-mal geändert.
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Pingu625

Beitrag von Pingu625 »

Also erstmal danke, für die ausführliche Antwort ;)

Dein preg_replace-Beispiel klappt super, aber das preg_match_all() macht immernoch Probleme:

Code: Alles auswählen

preg_match_all('|<!-- BEGIN '.$name.' -->(*.?)<!-- END '.$name.' -->|s', $this->content, $blocks, PREG_PATTERN_ORDER);
echo $blocks[1][0];
führt zu folgender Fehlermeldung:
Warning: preg_match_all(): Compilation failed: nothing to repeat at offset 20 in includes/template.class.php on line 83

Notice: Undefined offset: 1 in includes/template.class.php on line 84
Diese Linien sind eben die besagten, die oben zu sehen sind.

Der HTML Code lautet so:

Code: Alles auswählen

[...]
<body>
<!-- BEGIN name -->
abe <!-- END name -->
</body>
[...]
Und wie gesagt klappt an diesem Code das preg_replace ohne Probleme! :)

Pingu

EDIT: Hier ist eine Beispieldatei, wo man den Code & den Fehler sieht.
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Beitrag von gn#36 »

Tja da hat sich wohl auch ein Tippfehler eingeschlichen. Der Stern gehört hinter den Punkt nicht davor...

Code: Alles auswählen

<?php
$text = '<body>
<!-- BEGIN name -->
abe <!-- END name -->
</body> ';
$name = 'name';
preg_match_all('#<!-- BEGIN '.$name.' -->(.*?)<!-- END '.$name.' -->#s', $text, $blocks, PREG_PATTERN_ORDER);
echo $blocks[1][0];

?>
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Pingu625

Beitrag von Pingu625 »

Vielen Dank :)

Das funktioniert super.
Zum Glück gibt es noch Leute die sich mit diesen preg_replace-Funktionen und so auskennen. :P

Ich glaube, ich muss mir das auch mal genauer anschauen, auch wenn ich die Funktionen eher weniger brauche.

Pingu
Antworten

Zurück zu „Coding & Technik“