作为反向引用使用的转义序列 \g 并不总是按预期工作。
以下编号的反向引用指的是与指定捕获组匹配的文本,如文档中所述
\1
\g1
\g{1}
\g-1
\g{-1}
但是,以下变体指的是子模式代码而不是匹配的文本
\g<1>
\g'1'
\g<-1>
\g'-1'
对于命名反向引用,我们也可以使用 \k 转义序列以及 (?P=...) 结构。以下组合也指的是与命名捕获组匹配的文本,如文档中所述
\g{name}
\k{name}
\k<name>
\k'name'
(?P=name)
但是,这些指的是子模式代码而不是匹配的文本
g<name>
\g'name'
在下面的示例中,捕获组搜索单个字母“a”或“b”,然后反向引用搜索相同的字母。因此,这些模式预期匹配“aa”和“bb”,但不匹配“ab”或“ba”。
<?php
$patterns = [
'/([ab])\1/', '/([ab])\g1/', '/([ab])\g{1}/', '/([ab])\g<1>/', "/([ab])\g'1'/", '/([ab])\k{1}/', '/([ab])\k<1>/', "/([ab])\k'1'/", '/([ab])(?P=1)/', '/([ab])\-1/', '/([ab])\g-1/', '/([ab])\g{-1}/', '/([ab])\g<-1>/', "/([ab])\g'-1'/", '/([ab])\k{-1}/', '/([ab])\k<-1>/', "/([ab])\k'-1'/", '/([ab])(?P=-1)/', '/(?<name>[ab])\g{name}/', '/(?<name>[ab])\g<name>/', "/(?<name>[ab])\g'name'/", '/(?<name>[ab])\k{name}/', '/(?<name>[ab])\k<name>/', "/(?<name>[ab])\k'name'/", '/(?<name>[ab])(?P=name)/', ];
foreach ($patterns as $pat)
echo " '$pat',\t// " . var_export(@preg_replace($pat, 'xx', 'aa ab ba bb'), 1) . PHP_EOL;
?>