Verschachtelte reguläre Ausdrücke



  • Hallöchen,

    ich habe zurzeit ein Problem mit regulären Ausdrücken in einem Webprojekt in PHP, für das ich ein kleines Template-System schreibe.

    Ich möchte sozusagen verschachtelte reguläre Ausdrücke nutzen, z. B. soll ein regulärer Ausdruck einen if-Block finden und danach auf die Bedingung des if-Blocks auch nochmal ein anderer Ausdruck angewendet und das gesamte Konstrukt dann im Originalstring durch etwas anderes ersetzt werden.

    Das Beispiel mal als Code:

    <!--if({TEMPLATEVAR} = "test")-->
        <p>
            Die Templatevariable hat den Wert "test"!
        </p>
    <!--endif-->
    

    Hierbei müsste erstmal der if-Block gefunden werden und durch folgendes Schema

    <?php if(/* bedingung */) { ?>
        <!-- Inhalt des if-Blocks -->
    <?php } ?>
    

    ersetzt werden.
    Auf die Bedingung des gefundenen if-Blocks und eigentlich auch auf den Inhalt des Blocks müsste aber vor dem kompletten Ersetzen im Originalstring auch noch ein regulärer Ausdruck angewendet werden, damit z. B. {TEMPLATEVAR} durch seine Entsprechung (z. B. $template->variables["TEMPLATEVAR"]) ersetzt wird.

    Kurzes Script das meinen bisherigen Ansatz zeigt:

    <?php
    $text = <<<HEREDOC
    Text aussen rum!<br />
    <!--if(VAR = "test")-->VAR hat den Inhalt "test"!<br /><!--endif-->
    Noch mehr Text aussen rum!
    HEREDOC;
    
    $regex = "~<!--if\((.+)\)-->(.+)<!--endif-->~sU";
    $replacement = "<?php if($1) { ?>$2<?php } ?>";
    
    $replaced = preg_replace($regex, $replacement, $text);
    ?>
    

    Replaced hat dann den Inhalt:

    Text aussen rum!<br />
    <?php if(VAR = "test") { ?>VAR hat den Inhalt "test"!<br /><?php } ?>
    Noch mehr Text aussen rum!
    

    Mein derzeitiger regulärer Ausdruck findet also den if-Block, behält beim Ersetzen aber die dort geschriebene Bedingung und den Inhalt bei, da ich noch nicht wusste, wie ich auf etwas gefundenes nochmal einen regulären Ausdruck anwenden kann, bevor ich es im Originalstring ersetze.
    Eine Möglichkeit wäre denke ich, erst den if-Block zu ersetzen und nach der Ersetzung nach den Templatevariablen zu suchen (also Anwendung des regulären Ausdrucks für die Templatevariablen auf die Variable $replaced aus meinem Biespiel), aber das erscheint mir zu fehleranfällig und ungeschickt.

    Gibt es also eine Möglichkeit, auf den gefundenen String vor dem Ersetzen nochmal einen regulären Ausdruck anzuwenden?



  • Reguläre Ausdrücke sind hier mMn der falsche Weg. Das wird auf dauer zu wenig wartbar und zu unübersichtlich.

    Schreib nen Tokenizer für deine Template-Sprache, der das ganze Konstrukt in seine Bestandteile zerlegt. So kannst du auch besser auf Fehler reagieren (schließende Klammer vergessen, ein endif zuwenig/zuviel, ...)

    Wobei sich wieder die Frage des Aufwandes stellt. Warum nicht eine bestehende Template-Engine nutzen oder ganz drauf verzichten und natives PHP verwenden?



  • zwutz schrieb:

    Schreib nen Tokenizer für deine Template-Sprache, der das ganze Konstrukt in seine Bestandteile zerlegt. So kannst du auch besser auf Fehler reagieren (schließende Klammer vergessen, ein endif zuwenig/zuviel, ...)

    Eigentlich wirklich ein guter Tip! Werd ich mal drüber nachdenken.

    zwutz schrieb:

    Wobei sich wieder die Frage des Aufwandes stellt. Warum nicht eine bestehende Template-Engine nutzen oder ganz drauf verzichten und natives PHP verwenden?

    Das Projekt ist um Grunde nur eine Übung, wollte daran etwas herumbasteln und Erfahrungen sammeln.
    In Projekten, die ich für einen Kunden entwickle, greife ich meistens allein schon aus Zeitgründen auf fertige Libs etc. zurück.


Anmelden zum Antworten