2013-08-03 80 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 –