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) 是不规范或者不正确的(各语言标准不同,有的支持这种写法,有的不支持)
PHP 正则表达式
关于 LearnKu
推荐文章: