9.1. 反向引用条件( true )

未匹配的标注

正则表达式里的条件要用 ? 来定义,实际上,前面我们已经用过很多次了

  • ? 匹配前 1 个字符或者表达式,如果它存在的话

  • ?=?<= 匹配前面或者后面的文本,如果它存在的话

嵌入式条件的语法也使用了 ? ,不过就是处理的情况不同罢了

  • ?(1) 根据反向引用来进行条件处理(注意:1是反向引用的序号)

  • 根据环视来进行条件处理

反向引用条件:在前一个子表达式得以匹配的情况下才允许使用另一个表达式

语法: (?( 反向引用的序号 ) 如果反向引用为 true 则要匹配的内容 )

用代码来理解,大概就是表达式为 trueif 语句

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)     是不规范或者不正确的(各语言标准不同,有的支持这种写法,有的不支持)

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~