模式适用于 regex101 但不适用于服务器
Pattern works on regex101 but not on Server
我的模式:
/{LOOP:(\w+)[^}]*}((\s*?.?)*?){\/LOOP:}/
我的测试字符串:
<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()
returns:
2(PREG_BACKTRACK_LIMIT_ERROR).
regex101 告诉我“581 步中的 1 场比赛”怎么可能?还是步数与回溯无关?
我正在使用 PHP 版本 5.5.9-1ubuntu4.16 的 apache2 服务器。
在我的php.ini中,pcre.backtrack_limit
设置为1000000。
编辑:
根据 Alan Moore 的提示,我现在使用以下模式:
/{LOOP:(\w+)[^}]*}(.*?){\/LOOP:}/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:}/s", $test, $matches, PREG_SET_ORDER);
// $matches is now an emty array.
它可能不起作用,因为您的服务器的正则表达式引擎将 {
和 }
处理为描述有限重复的特殊字符(另请参阅 Regex Tutorial)。而 Regex101 页面做了一些假设。
当想要匹配 {
或 }
作为字符时,它们需要像 \{
或 \}
一样被转义,或者像 [{}]
然后他们被当作普通字符对待。
我建议转义这些字符,如下所示:
\{LOOP:(\w+)[^}]*\}((\s*?.?)*?)\{\/LOOP:\}
这个表达式也适用于 Regex101
注意: 某些风格的正则表达式将允许不匹配的 }
作为字符进行匹配,因此它可能不需要转义,但我发现它是逃避它的最佳实践。
php 在正则表达式中需要一个额外的反斜杠。在这种情况下,将 </code> 更改为 <code>\1
有效:
preg_match_all("/{LOOP:(\w+)[^}]*}(.*){\/LOOP:(\1)}/s", ...
或者,单反斜杠在这里可以用单引号引起来,您可以通过始终在正则表达式周围使用单引号来省去一些麻烦:
preg_match_all('/{LOOP:(\w+)[^}]*}(.*){\/LOOP:()}/s', ...
我的模式:
/{LOOP:(\w+)[^}]*}((\s*?.?)*?){\/LOOP:}/
我的测试字符串:
<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()
returns:
2(PREG_BACKTRACK_LIMIT_ERROR).
regex101 告诉我“581 步中的 1 场比赛”怎么可能?还是步数与回溯无关?
我正在使用 PHP 版本 5.5.9-1ubuntu4.16 的 apache2 服务器。
在我的php.ini中,pcre.backtrack_limit
设置为1000000。
编辑:
根据 Alan Moore 的提示,我现在使用以下模式:
/{LOOP:(\w+)[^}]*}(.*?){\/LOOP:}/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:}/s", $test, $matches, PREG_SET_ORDER);
// $matches is now an emty array.
它可能不起作用,因为您的服务器的正则表达式引擎将 {
和 }
处理为描述有限重复的特殊字符(另请参阅 Regex Tutorial)。而 Regex101 页面做了一些假设。
当想要匹配 {
或 }
作为字符时,它们需要像 \{
或 \}
一样被转义,或者像 [{}]
然后他们被当作普通字符对待。
我建议转义这些字符,如下所示:
\{LOOP:(\w+)[^}]*\}((\s*?.?)*?)\{\/LOOP:\}
这个表达式也适用于 Regex101
注意: 某些风格的正则表达式将允许不匹配的 }
作为字符进行匹配,因此它可能不需要转义,但我发现它是逃避它的最佳实践。
php 在正则表达式中需要一个额外的反斜杠。在这种情况下,将 </code> 更改为 <code>\1
有效:
preg_match_all("/{LOOP:(\w+)[^}]*}(.*){\/LOOP:(\1)}/s", ...
或者,单反斜杠在这里可以用单引号引起来,您可以通过始终在正则表达式周围使用单引号来省去一些麻烦:
preg_match_all('/{LOOP:(\w+)[^}]*}(.*){\/LOOP:()}/s', ...