加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – pcre.backtrack_limit的“单位”是什么?

发布时间:2020-12-13 22:52:28 所属栏目:PHP教程 来源:网络整理
导读:我遇到一个问题,其中带有复杂正则表达式的preg_replace()导致错误(PREG_BACKTRACK_LIMIT_ERROR),因为pcre.backtrack_limit太低,默认情况下设置为1,000,000.我把它设置为10,它适用于这个特定的应用程序. 我的问题是,什么是回溯限制,松散定义,“单位”? 1,000
我遇到一个问题,其中带有复杂正则表达式的preg_replace()导致错误(PREG_BACKTRACK_LIMIT_ERROR),因为pcre.backtrack_limit太低,默认情况下设置为1,000,000.我把它设置为10,它适用于这个特定的应用程序.

我的问题是,什么是回溯限制,松散定义,“单位”? 1,000数字是否与内存大小相对应?如果没有,它意味着什么?我试图了解在我的环境中对此有何合理设置.

关于preg_replace的参考:
http://us3.php.net/manual/en/pcre.configuration.php#ini.pcre.backtrack-limit

关于回溯的参考:
In regular expressions,what is a backtracking / back referencing?

解决方法

从 the PCRE source code开始,当“match()”以递归方式调用超过1,000次时,将返回此错误:

/* First check that we haven't called match() too many times,or that we
haven't exceeded the recursive call limit. */

if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);

这被转换为“PHP_PCRE_BACKTRACK_LIMIT_ERROR”错误here.

根据pcreapi手册页(见https://serverfault.com/a/408272/140833):

Internally,PCRE uses a function called match() which it calls
repeatedly (sometimes recursively). The limit set by match_limit is
imposed on the number of times this function is called during a match,
which has the effect of limiting the amount of backtracking that can
take place. For patterns that are not anchored,the count restarts
from zero for each position in the subject string.

我认为该单位因此类似于“回溯尝试次数”.虽然我不确定它是1对1.

这是一个用简单的“Catastrophic Backtracking”正则表达式隔离错误案例的演示:

<?php

ini_set('pcre.backtrack_limit',100);

for ($len = 1000; $len <= 1001; $len++) {

    $x = str_repeat("x",$len);
    $ret = preg_match("/x+x+y/",$x);

    echo "len = " . $len . "n";
    echo "preg_match = " . $ret . "n";
    echo "PREG_BACKTRACK_LIMIT_ERROR = " . PREG_BACKTRACK_LIMIT_ERROR . "n";
    echo "preg_last_error = " . preg_last_error() . "n";
    echo "n";
}

在此运行此代码:https://3v4l.org/EpaNC,以获得此输出:

len = 1000
preg_match = 0
PREG_BACKTRACK_LIMIT_ERROR = 2
preg_last_error = 0

len = 1001
preg_match = 
PREG_BACKTRACK_LIMIT_ERROR = 2
preg_last_error = 2

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读