Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning: preg_match(): Compilation failed: unrecognized character after (? or (?-

I have a code written by a previous programmer, a regex preg_match that is throwing a compilation error:

$regex_t = "/" . $op . "(?\\>[^" . $op . $cl . "]+)*" . $cl . "/s";
preg_match($regex_t, $text, $inner);

The warning that I receive is:

Warning: preg_match(): Compilation failed: unrecognized character after (? or (?- at offset 4

Also, I want to mention that at var_dump($regex_t) the value is:

string '/\{(?\>[^\{\}]+)*\}/s' (length=21)
like image 772
Cumatru Cosu Avatar asked Nov 06 '25 11:11

Cumatru Cosu


1 Answers

For a strange reason, the programmer has escaped the > (that is never needed).

Only these characters need to be escaped to obtain a literal character (outside a character class):

( ) ^ $ [ \ | . * + ?

{   # only in these cases: {n} {m,n} {m,}
    # where m and n are integers

+ the pattern delimiter

Most of the time an escaped character that doesn't need to be escaped (or that does not have a special meaning like \b \w \d ...) is simply ignored by the regex engine. But it's not the case here, because (?> is a fixed sequence to open an atomic group, and the sequence (? is not allowed except for these cases:

  • a non capturing group: (?:...)
  • an atomic group: (?>...)
  • an inline modifier: (?i) (?-i)
  • a non capturing group with inline modifiers: (?i:...) (?-i:...)
  • a lookaround: (?=...) (?!...) (?<=...) (?<!...)
  • a branch reset group: (?|...|...)
  • a conditional test: (?(condition)...|...)
  • a reference to a subpattern: (?1) (?-1) (?R)
  • a definition group: (?(DEFINE)...)
  • a named subpattern: (?<John>...) (?P<John>...) (?'John'...)
  • a reference to a named subpattern: (?&John) (?P>John)

So (?\ is not recognized as one of these sequences, this is why you obtain an error.

Perhaps the programmer wanted to write an atomic group (?>...) (This is probably the case, because since the group is repeated, using an atomic group reduces the backtracking if the following subpattern fails) or has forgotten the : for a non capturing group (?:\\ as Avinash suggests it, but to obtain a literal backslash you need four backslashes in a double quoted string.

like image 96
Casimir et Hippolyte Avatar answered Nov 08 '25 12:11

Casimir et Hippolyte