Warning: preg_match(): Compilation failed: unrecognized character after (? or (?-
php, preg-match, regex
Solution
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.
Problem
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) ```