background image

$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 (此处任意数目均可)作为回返指针。例如,如果你想把所有的段
落标签<p>都替换成文本:

$text = preg_replace( '/<p>(.*?)</p>/',
"&lt;p&gt;$1&lt;/p&gt;", $html );
参数$1 是一个回返引用,代表段落标签<p>内部的文字,并插入到替换后的文本里。

这种简便易用的表达式写法为我们提供了一个获取已匹配文字的简单方法,甚至在替换
文本时也能使用。

3. 已命名捕获组(Named Groups)
当在一个表达式内多次用到回调引用时,很容易就把事情搞混淆,要弄清那些数字

(1 … 9)都代表哪一个子内容是件很麻烦的事。回调引用的一个替代方法是使用带名字

的捕获组(下文简称 有名组 )。有名组使用(?P<name>pattern)来设定,name 代表组名,
pattern 是配合该有名组的正则结构。请看下面的例子:

/(?P<quote>"|').*?(?P=quote)/
上式中,quote 就是组名,"|'是改组匹配内容的正则。后面的(?P=quote)是在调用组名

为 quote 的有名组。这个式子的效果和上面的回调引用实例一样,只不过是用了有名组来
实现。是不是更加易读易懂了?

有名组也能用于处理已匹配内容之数组的内部数据。赋予特定正则的组名也能作为所

匹配到的内容在数组内部的索引词。

preg_match( '/(?P<quote>"|\')/', "'String'", $matches );

下面的语句输出 '”(不包括双引号)

echo $matches[1];

使用组名调用,也会输出 '”