模式适用于regex101,但不适用于服务器

时间:2016-05-06 22:41:05

标签: php regex preg-match-all pcre

我的模式:

/{LOOP:(\w+)[^}]*}((\s*?.?)*?){\/LOOP:\1}/

我的测试字符串:

<tbody>
    {LOOP:MENU}
    <tr>
        <td>{VAR:ID}</td>
        <td>{VAR:NAME}</td>
        <td>{VAR:ROLLE}</td>
        <td>{VAR:ACTIONS}</td>
    </tr>
    {/LOOP:MENU}
</tbody>

当你在regex101上试用它时它没有任何问题。但是当我在我的服务器上使用preg_match_all()进行尝试时,它无效。 preg_last_error()返回:

  

2(PREG_BACKTRACK_LIMIT_ERROR)。

如何通过regex101告诉我&#34; 1匹配581步&#34;?或者步骤的数量与Backtrack无关?

我正在使用PHP版本5.5.9-1ubuntu4.16的apache2服务器。

在我的php.ini中,pcre.backtrack_limit设置为1000000。

编辑:

根据Alan Moore的提示,我现在使用以下模式:

/{LOOP:(\w+)[^}]*}(.*?){\/LOOP:\1}/s

这返回0(NO_ERROR)。但在我的服务器上它现在不匹配任何东西。为什么它在regex101上工作但在我的服务器上却没有?

PHP:

$test="<tbody>
        {LOOP:MENU}
        <tr>
            <td>{VAR:ID}</td>
            <td>{VAR:NAME}</td>
            <td>{VAR:ROLLE}</td>
            <td>{VAR:ACTIONS}</td>
        </tr>
        {/LOOP:MENU}
       </tbody>"
preg_match_all("/{LOOP:(\w+)[^}]*}(.*?){\/LOOP:\1}/s", $test, $matches, PREG_SET_ORDER);
// $matches is now an emty array.

2 个答案:

答案 0 :(得分:0)

它可能不起作用,因为您的服务器的正则表达式引擎处理{}作为描述有限重复的特殊字符(另请参阅Regex Tutorial)。而Regex101页面做了一些假设。

如果想要将{}作为字符进行匹配,则需要像\{\}一样对其进行转义,或将其隐藏在方括号内{} {{} 1}}然后他们像常规字符一样对待。

我建议转义这些字符,如下所示:

[{}]

此表达式也适用于Regex101

注意:一些正则表达式将允许无法匹配的\{LOOP:(\w+)[^}]*\}((\s*?.?)*?)\{\/LOOP:\1\} 作为角色匹配,因此可能不需要转义,但我发现它是最好的练习逃避它。

答案 1 :(得分:0)

php需要额外的反斜杠在这里和那里的正则表达式。在这种情况下,将\1更改为\\1有效:

preg_match_all("/{LOOP:(\w+)[^}]*}(.*){\/LOOP:(\\1)}/s", ...

或者,单引号的单反斜杠是可以的,你可以通过在regexes周围使用单引号来省去一些麻烦:

preg_match_all('/{LOOP:(\w+)[^}]*}(.*){\/LOOP:(\1)}/s', ...