[REGEX] Verschachtelung (mal wieder)

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [REGEX] Verschachtelung (mal wieder)

    Nabend,

    bin sicher nich der erste, der das Problem hat, aber ich brauch mal ein paar Gedanken. Die Suche im Forum rief mir wieder UNGREEDY-Modifkatoren und Recursive Patterns ins Gedächtnis, aber es bleiben immer noch Probleme.

    Passt auf, folgendes Konstrukt:

    PHP-Code:
    <?php

    $string1 
    = <<<END

            <tpl:repeat name="gtp_tree">
     jkljk
                    <tpl:repeat name="chapter_tree">
                    <li>Seite <tpl:var name="page_nr" type="script" /></li>
                    </tpl:repeat>
    lkjkl
            </tpl:repeat>
            
            <tpl:repeat name="chapter">
            <li>Seite <tpl:var name="page" type="script" /></li>
            </tpl:repeat>        

    END;

        
    preg_match_all("/(<tpl:)([A-Za-z]*)( {1})(.*)((?<!\/)>)((.*)|(?R))(<\/tpl:)(\\2)(>)/isU"$string1$blocks);
        
        
    print_r($blocks);
    Man sieht schon, das ganze hat wieder was mit dem leidigen Template-Thema zu tun. Dieses Skript erfasst den zweiten repeat-Block mit dem Namen "chapter" korrekt, jedoch den ersten (verschachtelten) nur teilweise. Er nimmt wieder mal den Inneren, statt den Äußeren und schneidet so:
    PHP-Code:
    lkjkl
            
    </tpl:repeat
    natürlich ab. Ich brauche einen Ausdruck der sich sowohl nach /U richtet, aber trotzdem die Rekursion erkennt.
    "Geht nicht" gibts nicht, die Nasen von der Smarty-Template-Engine ham das auch hinbekommen und irgendwie parst der PHP-Interpreter ja auch bis ins Unendliche verschachtelte Konstrukte.

  • #2
    hüstel,

    ich hatte dazu im codeschnipsel forum schon mal was gepostet ...

    ich hab deinen regexp nicht sehr genau angeschaut, aber schau mal:
    http://pcre.nophia.de/evaluate/549dc...dex.php#output

    du mußt nur die bedingungen vertauschen ...
    Die Zeit hat ihre Kinder längst gefressen

    Kommentar


    • #3
      Danke für die kompetente Antwort. Deinen Code-Schnipsel hab ich gesehen und versucht anzuwenden -> Fehlanzeige, obwohl eigentlich alles identisch war.

      Jetzt hab ich durch Ausprobieren den Fehler gefunden: Folgende Anweisung liefert darauffolgende Ergebnisse:

      PHP-Code:
      preg_match_all("#(<tpl:)(repeat|if)( {1})(.*)(>)(((?R)|(.*))*)(</tpl:\\2>)#isU"$string1$blocks); 
      PHP-Code:
      Array
      (
          [
      0] => Array
              (
                  [
      0] => <tpl:repeat name="gtp_tree" bloed="bleib_bloed">
       
      jkljk
                      
      <tpl:repeat name="chapter_tree">
                      <
      li>Seite <tpl:var name="page_nr" type="script" /></li>
                      </
      tpl:repeat>
      lkjkl
              
      </tpl:repeat>
                  [
      1] => <tpl:repeat name="chapter_">
              <
      li>Seite <tpl:var name="page_" type="script" /></li>

              </
      tpl:repeat>
              )

          [
      1] => Array
              (
                  [
      0] => <tpl:
                  [
      1] => <tpl:
              )

          [
      2] => Array
              (
                  [
      0] => repeat
                  
      [1] => repeat
              
      )

              .
              .
              .
              .


      Genauso will ichs auch haben. Der Syntax der Template-Engine, die ich entwickle, sieht immer aus wie XML's Processing Instructions: <tpl:anweisung option1="wert1" option2="wert" (/)>[ein bissl code</tpl:anweisung>]
      Der Slash vor dem schließenden ">" im Start-Tag steht nur bei Einzelanweisungen, bei Block-Anweisungen fehlt dieser, dafür gibt es einen Schließ-Tag. Die Engine sucht allgemein solche Ausdrücke und lädt Module nach, die im Namen die "anweisung" haben. Man soll also ohne Probleme einfach entsprechende Module ins Library-Verzeichnis kopieren und neue Arten von Anweisungen nutzen zu können.
      Deswegen brauch ich eine dynamische Anweisung. Sobald ich aber den REGEX wie folgt umändere:

      PHP-Code:
      #(<tpl:)([a-z]*)( {1})(.*)(>)(((?R)|(.*))*)(</tpl:\\2>)#isU 
      findet der Ausdruck überhaupt nichts mehr. Oder ich versuche mit Hilfe von Assertions die Konvention des fehlenden Slashes vor dem Schluss-">" im Start-Tag durchzusetzen:

      PHP-Code:
      preg_match_all("#(<tpl:)(repeat|if)( {1})(.*)((?>!/)>)(((?R)|(.*))*)(</tpl:\\2>)#isU"$string1$blocks); 
      Wenn dir dazu noch was einfällt, is mein Problem gelöst.
      Zuletzt geändert von MaxPayne; 27.12.2004, 23:02.

      Kommentar

      Lädt...
      X