2016-11-21 3 views
1

Ich versuche, eine einfache Template-Engine in PHP für meine MVC-Framework zu kodieren. Ich schreibe eine Methode zu behandeln, wenn Bedingungen in meiner Vorlage mit einigen speziellen Tags.Regex Fehler, verschachtelte Tags

ich diesen Code schrieb:

<?php 
$text = '{% if var = val %} 

{%if var1 = var1 %} 
{% endif %} 

{% endif %} 

{%if var = val1 %} 

{%if var1 = var1 %} 
{% endif %} 

{% endif %}'; 


function check_condition($text) 
{ 
    /* 
    1 - preg_match_all (get all conditions) 
    2 - scroll all the conditions 
    2.1 - check if the condition is still present in the primary source 
    2.2 - resolve the condition and get the text to print 
    3 - replace the text in the primary source 
    */ 

//1 
if(preg_match_all('/{% if (.*) %}(.*){% endif %}/s', $text, $conditions)) 
{ 
    //2 
    foreach($conditions as $condition) 
    { 
     //2.1 
     if(preg_match('/'.$condition[0].'/', $text)) 
     { 
      //2.2 
      preg_match('/{% if (.*) %}/U', $condition[0], $data); 
      //check for and/or 

      $data = str_ireplace('{% if ', '', $data); 
      $data = str_ireplace(' %}', '', $data[0]); 
      $data = explode(' = ', $data); 

      if($data[0] == $data[1]) 
      { 
       //3 
       $text = str_ireplace($condition[0], 'some text'.$condition[0], $text); 
      } else { 
       //check for else 

      } 
     } 
    } 
} 
return $text; 
} 

echo check_condition($text); 

Der Text var ein Beispiel von Bedingungen enthalten, die Funktion ist nicht vollständig.

Diese Regex:

if(preg_match_all('/{% if (.*) %}(.*){% endif %}/s', $text, $conditions)) 

Sollte den gesamten Bedingungsblock, in diesem Fall erhalten:

[0] => '{% if var = val %} 

{%if var1 = var1 %} 
{% endif %} 

{% endif %}' 
[1] => '{%if var1 = var1 %} 
    {% endif %}' 
[2] => '{%if var = val1 %} 

{%if var1 = var1 %} 
{% endif %} 

{% endif %}' 
[3] => '{%if var1 = var1 %} 
{% endif %}' 

Aber es gibt einen einzigen Block mit dem gesamten Code (aus dem ersten {% if. .%} bis zum letzten {% endif%})

Das Problem ist mit den verschachtelten Bedingungen, ich denke, dass die Regex nicht damit umgehen kann. Wer hat irgendwelche Ideen? Wie kann ich das beheben? Gibt es noch eine andere Methode, die ich verwenden kann?

+0

Nur eine Randnotiz zur Lesbarkeit. Mit Instanzen wie "2.1" mache ich gerne etwas wie "if (! Condition) continue;", damit Sie nicht jedes Mal, wenn Sie eine Bedingung überprüfen, einen Einzug vornehmen müssen. – Sam

+0

ist es gierig. Verwenden Sie einen faulen Indikator '?' nach den übereinstimmenden Elementen innerhalb von Gruppierungen. – Cunning

Antwort

1

Nun .* passt alle Symbole, die es bekommen kann. Verwenden Sie die "faule" Version, indem Sie .* durch .*? ersetzen. Es sollte mit den minimal möglichen Zeichen übereinstimmen, die an den nächsten Teil des regulären Ausdrucks übergeben werden.

Aber das würde immer noch nicht geben, was Sie wollen, denke ich. start1 start2 end2 end1 wird auf start1-end2 übereinstimmen, obwohl es nicht sollte. Es sollte weitere Überprüfungen zwischen den if und endif geben, die andere darin enthaltene Paare berücksichtigen würden.

+0

Ja, ich denke, dass die Verwendung einer Regex nicht der beste Weg ist ... Kennen Sie Alternativen? –