2016-11-21 38 views
1

我想在我的MVC框架在PHP中編寫一個簡單的模板引擎。 我正在寫一個方法來處理如果我的模板中的條件,使用一些特殊的標籤。正則表達式錯誤,嵌套標籤

我寫了這個代碼:

<?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); 

文本VAR包含的條件的一個例子,該功能是不完整的。

此正則表達式:

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

應該得到整個條件塊,在這種情況下:

[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 %}' 

但它返回與整個代碼(由第一個{%如果單塊。 。%}到最後一個{%endif%})

問題是嵌套條件,我認爲正則表達式無法處理這個問題。 任何人有任何想法?我該如何解決這個問題? 還有其他方法可以使用嗎?

+0

只是一個關於可讀性的側面說明。有了像'2.1'這樣的實例,我喜歡做'if(!condition)continue'這樣的'',這樣你每次檢查條件時就不需要保留縮進。 – Sam

+0

它很貪婪。在匹配元素之後,在分組內部使用懶惰指示符'?'。 – Cunning

回答

1

那麼.*匹配它可以得到它的所有符號。 用.*?代替.*,嘗試使用「懶惰」版本。它應該匹配傳遞到正則表達式的下一部分的最小可能字符。

但這仍然不會給你你想要的,我猜。 start1 start2 end2 end1將在start1-end2上匹配,即使它不應該。在ifendif之間應該有一些更多的檢查,它們將包含其中的其他對。

+0

是的,我認爲使用正則表達式不是最好的方法... 你知道任何替代方案嗎? –