正则表达式的高级技巧8个常用的概念(2)
2. 回返引用(Back referencing)
有什么用?
回返引用(Back referencing)一般被翻译成“反向引用”、“后向引用”、“向后引用”,个人觉得“回返引用”更为贴切[笨活儿]。它是在正则表达式内部引用之前捕获到的内容的方法。例如,下面这个简单例子的目的是匹配出引号内部的内容:
# 建立匹配数组
$matches = array();
# 建立字串
$str = "\"This is a 'string'\"";
# 用正则表达式捕捉内容
preg_match( "/(\"|').*?(\"|')/", $str, $matches );
# 输出整个匹配字串
echo $matches[0];
它会输出:
"This is a'
显然,这并不是我们想要的内容。
这个表达式从开头的双引号开始匹配,遭遇单引号之后就错误地结束了匹配。这是因为表达式里说:("|'),也就是双引号(")和单引号(')均可。要修正这个问题,你可以用到回返引用。表达式\1,\2,…,\9 是对前面已捕获到的各个子内容的编组序号,能作为对这些编组的“指针”而被引用。在此例中,第一个被匹配的引号就由1代表。
如何运用?
将上面的例子中,后面的闭合引号替换为1:
preg_match( '/("|\').*?\1/', $str, $matches );
这会正确地返回字串:
"This is a 'string'"
译注思考题:
如果是中文引号,前引号和后引号不是同一个字符,怎么办?
还记得PHP函数 preg_replace 吗?其中也有回返引用。只不过我们没有用 \1 … \9,而是用了 $1 … $9 … $n (此处任意数目均可)作为回返指针。例如,如果你想把所有的段落标签都替换成文本:
$text = preg_replace( '/<p>(.*?)< \/p>/',
'<p>$1</p>', $html );
参数$1是一个回返引用,代表段落标签内部的文字,并插入到替换后的文本里。这种简便易用的表达式写法为我们提供了一个获取已匹配文字的简单方法,甚至在替换文本时也能使用。