9.1. 反向引用条件( true )
正则表达式里的条件要用 ?
来定义,实际上,前面我们已经用过很多次了
?
匹配前 1 个字符或者表达式,如果它存在的话?=
和?<=
匹配前面或者后面的文本,如果它存在的话
嵌入式条件的语法也使用了 ?
,不过就是处理的情况不同罢了
?(1)
根据反向引用来进行条件处理(注意:1是反向引用的序号)根据环视来进行条件处理
反向引用条件:在前一个子表达式得以匹配的情况下才允许使用另一个表达式
语法: (?( 反向引用的序号 ) 如果反向引用为 true 则要匹配的内容 )
用代码来理解,大概就是表达式为 true
的 if
语句
if($a == 1){$b = 1;}
例如:你要把一段文本中的 <img>
标签全部找出来
如果 <img>
标签是一个 <a>
和</a>
标签之间的话,那你还需要匹配整个链接标签
<?php
//字符串
$str = '
<div>
<img src="" alt="匹配 img1 成功">
<a><img src="" alt="匹配 img2 成功">/a>
</div>
';
//正则表达式
$regular = '/(<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*<\/[Aa]>)/';
//执行匹配正则表达式
preg_match_all($regular, $str, $matches);
//打印结果
echo '<pre>';
print_r($matches);
echo '</pre>';
输出结果
Array
(
[0] => Array
(
[0] => 匹配 img1 成功
[1] => 匹配 img2 成功
)
[1] => Array
(
[0] =>
[1] =>
)
)
下面我们来解释一下这个表达式
(<[Aa]\s+[^>]+>\s*)?
匹配一个 <A>
或 <a>
标签,及可能存在的任意属性,因为这个表达式最后有一个 ?
,所以这个 a
标签可有可无
<[Ii][Mm][Gg]\s+[^>]+>
匹配一个 <img>
标签(大小写都可以)及其任意属性
(?(1)\s*<\/[Aa]>)
?(1) 表示仅当第一个反向引用 (<a>标签)
存在,才能继续匹配 \s*<\/[Aa]>
?(1) 检查第一个反向引用是否存在,大家一定很奇怪,为什么这里的反向引用 1 不加 \ 符号?,那是因为在嵌入式条件中,反向引用不需要被转义。
所以
?(1) 是正确的
?(\1) 是不规范或者不正确的(各语言标准不同,有的支持这种写法,有的不支持)
推荐文章: