2013-08-03 83 views
0

我正在嘗試編寫一個PHP模板引擎。PHP模板引擎正則表達式

考慮以下字符串:

@foreach($people as $person) 
    <p></p> 
$end 

我可以使用下面的正則表達式來找到它:

@[\w]*\(.*?\).*[email protected] 

但是,如果我有這樣的字符串:

@cake() 
    @cake() 
     @fish() 
     @end 
    @end 
@end 

的正則表達式失敗,這是它發現:

@cake() 
    @cake() 
     @fish() 
     @end 

在此先感謝。

+1

這不是答案,但是您的模板引擎看起來並不比使用PHP作爲引擎本身更方便。 – invisal

+0

PHP不支持視圖繼承:P –

+0

@Petter:[Smarty的模板繼承。](http://www.smarty.net/inheritance) – icktoofay

回答

0

您有嵌套,它會將您帶出正規語法領域,這意味着您無法使用正則表達式。一些正則表達式引擎(可能包含PHP)具有可以識別一些嵌套表達式的功能,但這隻會帶你到目前爲止。看看傳統的解析工具,它應該能夠處理你的工作負載。 This question進入其中一些。

+0

好吧..你有什麼指針可以在哪裏找到「解析工具」? –

+0

@Petter:[這個問題](http://stackoverflow.com/q/2093228)經歷了其中的一些。不幸的是,即使你有一個合適的工具,它可能並不明顯,如何使用它。我不確定在PHP中執行解析器會有多少進展; PHP不是那種非常流行的語言。如果你走這條路,你可能需要對解析技術做更多的研究。 – icktoofay

+0

好的,謝謝。我想我有一個解決方案,但我只需要逐行讀取字符串並計算@something()和@ end的數量。並等到兩者的數量相等。 –

2

您可以匹配嵌套的功能,例如:

$pattern = '~(@(?<func>\w++)\((?<param>[^)]*+)\)(?<content>(?>[^@]++|(?-4))*)@end)~'; 

或不命名捕獲:

$pattern = '~(@(\w++)\(([^)]*+)\)((?>[^@]++|(?-4))*)@end)~'; 

請注意,你可以擁有的所有嵌套函數的所有內容,如果你把整個模式在先行(?=...)

圖案的詳細資料:

~    # pattern delimiter 
(    # open the first capturing group 
    @(\w++)  # function name in the second capturing group 
    \(   # literal (
    ([^)]*+)  # param in the third capturing group 
    \)   # literal) 
    (   # open the fourth capturing group 
    (?>   # open an atomic group 
     [^@]++ # all characters but @ one or more times 
     |   # OR 
     (?-4) # the first capturing group (the fourth on the left, from the current position) 
    )*   # close the atomic group, repeat zero or more times 
    )   # close the fourth capturing group 
    @end   
)~    # close the first capturing group, end delimiter 
+0

哇,太棒了!謝謝:)我應該學習如何工作。你知道這些先進的正則表達式的任何資源,如書籍或視頻嗎? (對我來說他們看起來相當先進) –

+0

@PetterThowsen:你可以在這裏找到更多關於遞歸正則表達式的信息:http://www.rexegg.com/regex-recursion.html –