我有一个由以前的程序员编写的代码,一个regex preg_match引发编译错误:
$regex_t = "/" . $op . "(?''>[^" . $op . $cl . "]+)*" . $cl . "/s";
preg_match($regex_t, $text, $inner);
我收到的警告是:
警告:preg_match():编译失败:无法识别的字符在(?或(?-偏移4 之后
此外,我想提到的是,在var_dump($regex_t)
,值为:
string '/'{(?'>[^'{'}]+)*'}/s' (length=21)
由于一个奇怪的原因,程序员逃离了>
(这是永远不需要的)。
只有这些字符需要转义才能获得文字字符(在字符类之外):
( ) ^ $ [ ' | . * + ?
{ # only in these cases: {n} {m,n} {m,}
# where m and n are integers
+图案分隔符
大多数情况下,正则表达式引擎会简单地忽略不需要转义的转义字符(或者像'b
'w
'd
…这样没有特殊含义的转义字符)。但这里的情况并非如此,因为(?>
是打开原子组的固定序列,并且除了以下情况之外,不允许使用(?
序列:
- 非捕获组:
(?:...)
- 原子团:
(?>...)
- 内联修饰符:
(?i)
(?-i)
- 具有内联修饰符的非捕获组:
(?i:...)
(?-i:...)
- 环视:
(?=...)
(?!...)
(?<=...)
(?<!...)
- 一个分支复位组:
(?|...|...)
- 条件测试:
(?(condition)...|...)
- 对子模式的引用:
(?1)
(?-1)
(?R)
- 定义组:
(?(DEFINE)...)
- 命名子模式:
(?<John>...)
(?P<John>...)
(?'John'...)
- 对命名子模式的引用:
(?&John)
(?P>John)
所以(?'
没有被识别为这些序列之一,这就是为什么你会得到一个错误。
也许程序员想写一个原子组(?>...)
(可能是这样,因为由于组是重复的,如果下面的子模式失败,使用原子组可以减少回溯),或者像Avinash建议的那样,忘记了非捕获组(?:''
的:
,但要获得一个字面反斜杠,您需要在一个双引号字符串中使用四个反斜杠。