条件子模式

可以根据断言的结果或先前捕获的子模式是否匹配来使匹配过程有条件地服从子模式或在两个备用子模式之间进行选择。条件子模式的两种可能形式是

(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

如果条件满足,则使用 yes-pattern;否则使用 no-pattern(如果存在)。如果子模式中有两个以上的备选项,则会发生编译时错误。

有两种类型的条件。如果括号之间的文本由一系列数字组成,则当该数字的捕获子模式先前已匹配时,该条件将得到满足。考虑以下模式,其中包含非显著空格以使其更具可读性(假设PCRE_EXTENDED 选项)并将其分为三个部分以便于讨论

( \( )? [^()]+ (?(1) \) )

第一部分匹配一个可选的左括号,如果该字符存在,则将其设置为第一个捕获的子字符串。第二部分匹配一个或多个不是括号的字符。第三部分是一个条件子模式,测试第一组括号是否匹配。如果它们匹配,也就是说,如果主题以左括号开头,则条件为 true,因此执行 yes-pattern,并且需要右括号。否则,由于 no-pattern 不存在,子模式将不匹配任何内容。换句话说,此模式匹配一系列非括号,可选地用括号括起来。

如果条件是字符串 (R),则如果对模式或子模式进行了递归调用,则该条件将得到满足。在“顶级”级别,该条件为 false。

如果条件不是一系列数字或 (R),则它必须是一个断言。这可能是一个肯定或否定前瞻或后顾断言。考虑这个模式,它也包含非显著空格,并且在第二行有两个备选项

(?(?=[^a-z]*[a-z])
\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )

该条件是一个肯定的前瞻断言,它匹配一个可选的非字母序列,后面跟着一个字母。换句话说,它测试主题中是否存在至少一个字母。如果找到字母,则主题将与第一个备选项匹配;否则它将与第二个备选项匹配。此模式匹配以下两种形式之一的字符串:dd-aaa-dd 或 dd-dd-dd,其中 aaa 是字母,dd 是数字。

添加说明

用户贡献的说明 1 条说明

3
匿名
13 年前
子模式的重复将重复其中包含的条件语句,并使用迭代更新子模式匹配。

考虑以下代码,它扫描 HTML,跟踪尖括号“<”和“>”。如果左括号“<”匹配,则在重复结束之前必须有右括号“>”跟随。这样,正则表达式将有效地仅匹配标签之外的部分。

<?php
$pattern
='%(*ANY)(.*?(<)(?(2).*?>)(.*?))*?\'\'%s';
$replace='\1Fred';
$subject=
'<html><body class=\'\'>\'\' went to '\'\meyer and ran
into <b>\'\'</b>.
</body></html>'
echo preg_replace("%(*ANY)(.*?((<)(?(3).*?>).*?)*?)\'\'%s",'\1Fred',$subject);
?>

输出将是
'<html><body class=\'\'>Fred went to Fredmeyer and ran
into <b>Fred</b>.
</body></html>'
To Top