Php 奇怪的正则表达式问题

Php 奇怪的正则表达式问题,php,regex,Php,Regex,我想我可能忽略了一些事情,但我不确定为什么会发生这种奇怪的行为 <?php // < 15 "a" characters returns "aaaaaaaaaaaaaa {" (no matches) $code = 'aaaaaaaaaaaaaa {'; // 15 "a" characters returns NULL $code = 'aaaaaaaaaaaaaaa {'; $code = preg_replace('#(a+)+\{#', 'b', $code); var_

我想我可能忽略了一些事情,但我不确定为什么会发生这种奇怪的行为

<?php
// < 15 "a" characters returns "aaaaaaaaaaaaaa {" (no matches)
$code = 'aaaaaaaaaaaaaa {';
// 15 "a" characters returns NULL
$code = 'aaaaaaaaaaaaaaa {';

$code = preg_replace('#(a+)+\{#', 'b', $code);
var_dump($code);
?>
我知道这是一个荒谬的正则表达式捕获,但我的问题是为什么会发生这种情况

<?php
// < 15 "a" characters returns "aaaaaaaaaaaaaa {" (no matches)
$code = 'aaaaaaaaaaaaaa {';
// 15 "a" characters returns NULL
$code = 'aaaaaaaaaaaaaaa {';

$code = preg_replace('#(a+)+\{#', 'b', $code);
var_dump($code);
?>
所以我用了正则表达式:

#([^\s\{\}]+\s*)+\{#msi
它也使用double+。有没有更好的方法,为什么这会首先引起问题

编辑2: 从下面的答案来看,double+似乎会导致很多反向引用,应该避免。我选择了这个
[^\s\{}][^\{}]*+\{

<?php

ini_set('pcre.backtrack_limit',20000);
$code = 'aaaaaaaaaaaaaaa {';
$code = preg_replace('#(a+)+\{#', 'b', $code);
var_dump($code, preg_last_error());

ini_set('pcre.backtrack_limit',1000000);
$code = 'aaaaaaaaaaaaaaa {';
$code = preg_replace('#(a+)+\{#', 'b', $code);
var_dump($code, preg_last_error());
但是您确实应该使用
(a+
(a)+
,而不是两者的组合


但是你真的应该使用
(a+
(a)+
,而不是两者的结合。

罪魁祸首必须是奇怪的
(a++++
模式——为什么要在同一模式上加倍
+
量词?删除第二个
+
应该可以解决问题。你能
变量转储(preg\u last\u error())
?我认为回溯限制是由于Jon提到的问题(如果正则表达式匹配内部或外部的
+
?)而达到的。顺便说一句,我在这里工作……回溯限制=1000,000@Wrikken:你说得对。我的系统最多可以使用17个“a”字符,但在更长的时间内都会失败。但是
preg\u last\u error
为int(0)@纳扎里:这不是重点,问题是为什么会返回NULL。罪魁祸首必须是奇怪的
(a+++
模式——为什么要在同一模式上加倍
++
量词?删除第二个
++
应该可以解决问题。你能
变量转储(preg\u last\u error())吗
?我认为回溯限制是由于Jon提到的问题(如果正则表达式匹配内部或外部的
+
?)而达到的。顺便说一句,我在这里工作……回溯限制=1000,000@Wrikken:你说得对。我的系统最多可以使用17个“a”字符,但在更长的时间内都会失败。但是
preg\u last\u error
为int(0)@纳扎里:这不是重点,问题是为什么返回NULL。那么它的回溯内存就用完了。不好。贪婪的+不会捕获所有的“a”字符并停在那里吗?看到有人以正确的方式使用正则表达式总是好的。@AramKocharyan不。更高级语句的贪婪
(a++)
位于较低级别的
a+
语句之前。然后
(a+)
捕获单个a,然后
(a+)
决定继续并
(a+)
捕获另一个a等等?正则表达式引擎和您一样混乱,并尝试匹配的每一个排列。因此,大量的回溯是毁灭性的。这不是内存问题,这是一个指示“如果您需要大量的回溯,可能有点不对劲”的设置。我想要一个功能,其中preg*函数实际上会发出一个错误(警告或通知),而不是“静默”失败。因此,它会耗尽用于回溯的内存。不好。贪婪的+不会捕获所有的“a”字符,到此为止?很高兴看到有人使用具有适当意义的正则表达式。@AramKocharyan没有。高级语句
(a++)
的贪婪程度先于低级语句
(a+)
的贪婪程度。然后
(a+)
捕获单个a,然后
(a+)
决定继续并
(a+)
捕获另一个a等等?正则表达式引擎和您一样混乱,并尝试匹配的每一个排列。因此,大量的回溯是毁灭性的。这不是内存问题,这是一个指示“如果您需要大量的回溯,可能有点不对劲”的设置。我想要一个功能,其中preg*函数实际上会发出错误(警告或通知),而不是“静默”失败。
NULL
int(2)
string(17) "aaaaaaaaaaaaaaa {"
int(0)