问题描述
function recursiveSplit($string, $layer) {
$err = preg_match_all("/\{(([^{}]*|(?R))*)\}/",$string,$matches);
echo "Elementi trovati: $err<br>";
if($err == FALSE) echo "preg_match_all ERROR<br>";
// iterate thru matches and continue recursive split
if (count($matches) > 1) {
for ($i = 0; $i < count($matches[1]); $i++) {
if (is_string($matches[1][$i])) {
if (strlen($matches[1][$i]) > 0) {
echo "<pre>Layer ".$layer.": ".$matches[1][$i]."</pre><br />";
recursiveSplit($matches[1][$i], $layer + 1);
}
}
}
}
}
$buffer = "{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{aaaaaaaaaaaaaaaaaa{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}";
recursiveSplit($buffer, 0);
输出
Elementi trovati:
preg_match_all ERROR
Backtrack limit was exhausted!
这段代码给我一个PREG_BACKTRACK_LIMIT_ERROR错误...但是回溯限制设置为100.000.000.
this code gives me a PREG_BACKTRACK_LIMIT_ERROR error... but the backtrack limit is set to 100.000.000.
这是我第一次使用正则表达式,我真的不知道该如何解决.
This is my first time with regex, and I really do not know how to solve it.
非常感谢你,马可
推荐答案
灾难性的另一种经典案例回溯.今天必须是我的幸运日.
/\{(([^{}]*|(?R))*)\}/
仅在大括号正确嵌套的情况下匹配.当然,它们不在您的字符串中.
only matches if the braces are nested correctly. Which they aren't, of course, in your string.
现在的问题是,您的正则表达式需要找出可以使用106 a
生成的所有可能的字符串组合,以找出原因,因为您有嵌套的量词((...)*)*)
.哪个(如果我错了,请纠正我)应该在106!
的附近
Now the problem is that your regex needs to figure out all possible string combinations you can build with 106 a
s to figure that out because you have nested quantifiers ((...)*)*)
. Which (correct me if I'm wrong) should be somewhere in the vicinity of 106!
which comes to
114628056373470835453434738414834942870388487424139673389282723476762012382449946252660360871841673476016298287096435143747350528228224302506311680000000000000000000000000
114628056373470835453434738414834942870388487424139673389282723476762012382449946252660360871841673476016298287096435143747350528228224302506311680000000000000000000000000
轻松击败您的PREG_BACKTRACK_LIMIT.
which easily beats your PREG_BACKTRACK_LIMIT.
如果您使用所有量词,以确保您永远不会回溯到您已经匹配的非大括号,那么您应该没问题:
If you use possessive quantifiers to make sure that you'll never backtrack into the non-braces you've already matched, then you should be OK:
/\{(([^{}]*+|(?R))*)\}/
这篇关于PHP:意外PREG_BACKTRACK_LIMIT_ERROR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!