PHP模板引擎正则表达式

PHP模板引擎正则表达式,php,regex,template-engine,Php,Regex,Template Engine,我正在尝试编写一个PHP模板引擎 考虑以下字符串: @foreach($people as $person) <p></p> $end 但是如果我有这个字符串: @cake() @cake() @fish() @end @end @end 正则表达式失败,它会发现: @cake() @cake() @fish() @end 提前感谢。您有嵌套,这使您脱离了常规语法的范畴,

我正在尝试编写一个PHP模板引擎

考虑以下字符串:

@foreach($people as $person)
    <p></p>
$end
但是如果我有这个字符串:

@cake()
    @cake()
        @fish()
        @end
    @end
@end
正则表达式失败,它会发现:

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

提前感谢。

您有嵌套,这使您脱离了常规语法的范畴,这意味着您不能使用正则表达式。一些正则表达式引擎(可能包括PHP)具有一些特性,可以让您识别一些嵌套表达式,但这仅限于此。看看传统的解析工具,它们应该能够处理您的工作负载。您可以匹配嵌套函数,例如:

$pattern = '~(@(?<func>\w++)\((?<param>[^)]*+)\)(?<content>(?>[^@]++|(?-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

好啊你有没有任何指向哪里可以找到“解析工具”的指针?@Petter:浏览了其中一些。不幸的是,即使你有了一个合适的工具,如何使用它也不太明显。我不确定在PHP中进行解析器的工作是否有那么多;PHP在这方面不是一种非常流行的语言。如果你沿着这条路走下去,你可能需要对解析技术做更多的研究。好的,谢谢。不过我想我有一个解决方案,我只需要逐行读取字符串并计算@something()和@end的数量。然后等待,直到两者的数量相等。这不是答案,但您的模板引擎看起来并不比简单地使用PHP作为引擎本身更方便。PHP不支持视图继承:P@Petter:使用include和function,可以使其看起来像视图继承。例如:哇,太棒了!谢谢:)我应该知道这是怎么回事。你知道这些高级正则表达式的书籍或视频等资源吗?(对我来说,它们似乎相当先进)@PetterThowsen:你可以在这里找到关于递归正则表达式的更多信息:
$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