递归正则表达式不匹配模板块

时间:2013-03-18 14:13:52

标签: php regex pcre

我正在尝试更多地了解正则表达式,在这种情况下,您可以在正则表达式中进行递归。

我正在尝试匹配{foreach $VAR} ... {/foreach}的嵌套块。但由于某种原因,我的正则表达式不匹配,我不明白为什么。

我希望这里的任何人能够对此有所了解。我对快速正则表达式修复感兴趣。但更多的是为什么我的正则表达式没有做我期望的事情。究竟发生了什么?

这是我的代码:

<?php
$str = 'start of text
{foreach $ABC}
  in 1st loop
  {foreach $XYZ}
    in 2nd loop
  {/foreach}
{/foreach}
some other stuff';

if ( preg_match ( '#{foreach \$.*?}((?!foreach)|(?R))*{/foreach}#', $str, $matches ) )
{
    print_r($matches);
}
else
{
    echo 'No match';
}

以下是我的正则表达式的细分,我认为它是如何运作的:

{foreach \$     #match literally "{foreach $"
.*?}            #followed by any character ending with a '}'
(               # start a group
  (?!foreach)   # match any character, aslong as it's not the sequence 'foreach'
  |             # otherwise
  (?R)          # do a recursion
)               # end of group
*               # match 0 or more times with a backtrace...
{/foreach}      # ...backtracing until you find the last {/foreach}

这就是我认为正则表达式的工作原理。但显然事实并非如此。所以我的问题是,我的解释在哪里错了?

您可以在此处使用此代码:http://codepad.viper-7.com/508V9w


只是澄清一下。

我正在尝试获取每个foreach块的内容。所以在我的情况下:

arr[0] => in 1st loop
      {foreach $XYZ}
        in 2nd loop
      {/foreach}
arr[1] => in 2nd loop

或 -

arr[0] => {foreach $ABC}
      in 1st loop
      {foreach $XYZ}
        in 2nd loop
      {/foreach}
    {/foreach}
arr[1] => {foreach $XYZ}
        in 2nd loop
      {/foreach}

要么会好起来的。

1 个答案:

答案 0 :(得分:0)

首先,.确实匹配除默认情况下的换行符。要使其与换行符匹配,您必须设置修饰符s

其次,你在这里使用断言:((?!foreach)|(?R))*,但没有匹配的实际字符。在*量词之前至少需要一个点。

#{foreach \$.*?}((?!foreach)|(?R)).*{/foreach}#s为您的测试文字提供以下结果:

Array
(
    [0] => {foreach $ABC}
  in 1st loop
  {foreach $XYZ}
    in 2nd loop
  {/foreach}
{/foreach}
    [1] => 
)