I think I may have overlooked something here, but I'm not sure why this strange behaviour is occurring.
I know this is a nonsensical regex capture, but my question is why is this occurring.
<?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);
?>
I realise that the regex has a \s
missing. If I change the regex to #(a+)+\s\{#
I get "b"
. But why don't I get "aaaaaaaaaaaaaaa {"
with 15 "a" characters instead of a NULL
? The manual states that NULL
is returned when an error occurs, but nothing is being printed out by PHP (error checking is on).
EDIT:
The reason I am using (a+)+
is because I am trying to simplify the problem down to the basic level. I started off with this:
I want to capture a series of non-whitespace characters followed by spaces followed by an opening brace.
this is some text {
So I used the regex:
#([^\s\{\}]+\s*)+\{#msi
Which also uses the double +. Is there a better way, and why is this causing an issue in the first place?
EDIT 2: From the answers below, it appears that the double + causes a lot of backreferences and should be avoided. I have opted for this [^\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());
Result:
NULL
int(2)
string(17) "aaaaaaaaaaaaaaa {"
int(0)
But you really should use either (a+)
or (a)+
, not a combination of both.