0

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

考虑以下字符串:

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

我可以使用以下正则表达式来找到它:

@[\w]*\(.*?\).*?@end

但是如果我有这个字符串:

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

正则表达式失败,这是它发现的:

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

提前致谢。

4

2 回答 2

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
于 2013-08-03T06:28:20.117 回答
0

You have nesting, which takes you out of the realm of a regular grammar, which means that you can't use regular expressions. Some regular expression engines (PHP's included, probably) have features that let you recognize some nested expressions, but that'll only take you so far. Look into traditional parsing tools, which should be able to handle your work load. This question goes into some of them.

于 2013-08-03T04:46:17.150 回答