首页/开发/正则与编码速查/条件匹配的语法与适用场景
正则进阶45 条

条件匹配的语法与适用场景

条件匹配写成 (?(组号或组名)yes|no),按前面某个组是否参与匹配来选分支,适合处理「可选前缀决定后续格式」的场景。PCRE、Perl、.NET 支持完整语法,Python re 只支持按组号或组名,断言条件与 Java 均不支持。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​‌‌​​‌​​​‌‌​‌​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​‌‌​​​​‌​‌‌​‌‌​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌​​​​‌​‌‌‌​‌​​​‌‌‌​‌​​​‌‌​​‌​‌​‌‌‌​​‌​​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​​​‌​​‌‌​​​​‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

条件匹配是什么

条件匹配让模式根据「前面某个组有没有参与匹配」决定后面走哪个分支,写法是 (?(条件)匹配则用|否则用)。它解决的是「同一段文本有两种合法形态」的问题:比如引号可有可无,一旦出现开头引号,结尾就必须也有。相比拆成两条模式按顺序尝试,条件把两种形态写在一处,代价是引擎支持面窄、可读性差。

基本信息

语法形态(?(1)yes|no) 按组号,(?(name)yes|no) 按组名,no 分支可省略
断言条件(?(?=regex)yes|no),仅 PCRE、Perl、.NET 等支持,Python re 不接受
支持情况PCRE/PHP、Perl、.NET 支持完整;Python re 支持按组号与组名;Java 不支持
判定依据判断的是该组在本次匹配中是否参与了,与组内文本长短无关

典型使用场景

  • 可选取值定界:开头有引号时才强制结尾也有引号,避免把交叉写法当成合法
  • 可选前缀决定长度:出现国家码时号码位数用一种规则,否则用另一种
  • 单位后缀影响格式:数字带大小写单位时才要求小数位,否则只允许整数
  • 把两三种分支收敛到一条模式里,减少调用方按顺序试探模式的代码量
  • PCRE 递归场景中判断当前是否处于递归调用内,用来区分首层与嵌套层

条件匹配写法示例

条件匹配写法示例
(a)?(?(1)b|c)                        # 组 1 参与就要求 b,未参与则要求 c
(?P<q>['"])?(?P<v>[^'"]*)(?(q)['"])  # 有开头引号才要求结尾引号
(?(?=x)y|z)                          # 断言条件,仅 PCRE、Perl、.NET 支持
(?(R)z|y)                            # PCRE:处于递归调用内则匹配 z
(?(DEFINE)(?<byte>0[xX][0-9A-F]+))   # PCRE 定义块,只定义子模式不参与匹配

引擎支持对照

引擎按组号/组名断言条件递归条件
PCRE / PHP / Perl支持支持支持 (?(R)…)
Python re支持,且组必须已出现不支持,会编译报错不支持
.NET支持支持不支持
Java不支持不支持不支持
条件里引用的组必须先出现在它前面:Python re 对引用后文组会直接报 invalid group reference,PCRE 也有类似约束,改写模式时把被判断的组整体前移是常见修法。
条件判断的是参与与否而不是内容是否为空:用 * 或 ? 声明的组即使匹配到空字符串也算参与,此时仍走 yes 分支,用「有没有引号」这类需求做判断时要把量词写准确。

易错点

  • 把条件当成内容判断:想知道引号里是不是空,得用断言或量词控制,条件本身只看组有没有参与
  • 条件引用了写在后面的组:编译期就报错,跨引擎搬运模式时表现为模式直接不可用
  • 在 Java 上使用条件匹配:语法不被接受,必须改用交替分支加代码侧判定
  • 把断言条件写进 Python re:(?(?=x)y|z) 这类写法会报组名非法,需要改写成先捕获再判断
  • no 分支省略带来语义惊喜:(?(1)b) 在不满足条件时要求匹配空串,等价于放宽约束,容易误判为校验通过

数据来源与参考

  • PCRE2 官方文档:pcre2pattern(Conditional subpatterns 章节)
  • Python 官方文档 re 模块:条件匹配 (?(id/name)yes-pattern|no-pattern)
  • .NET 官方文档:正则表达式交替构造

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/conditional-pattern-basics.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​‌‌​​‌​​​‌‌​‌​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​‌‌​​​​‌​‌‌​‌‌​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌​​​​‌​‌‌‌​‌​​​‌‌‌​‌​​​‌‌​​‌​‌​‌‌‌​​‌​​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​​​‌​​‌‌​​​​‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​