分支重置分组的作用范围
分支重置写成 (?|…),组内每个交替分支都从同一个序号重新开始编号,让不同分支里位置相同的字段共用组号。没有它时,交替会让各组号依次往后排,代码侧就得为每个分支写一套取值逻辑;用了它,两种格式的「年月日」可以都落在组 1、2、3 上。
基本信息
| 写法 | (?|分支一|分支二|…),只能包含交替分支 |
|---|---|
| 作用范围 | 仅重置该组内部的组号计数,外层组号在其之后继续递增 |
| 编号规则 | 各分支从左到右依次分配相同序号,分支长度不同时以最长的分支决定该组占用的序号数量 |
| 支持情况 | PCRE/PHP、Perl 5.10 起、Java 7 起、Boost 支持;Python re 与 JS 不支持,需改用命名组 |
典型使用场景
- 两种日期格式归一:圆点与斜杠写法都让年、月、日落在同样的组号上
- 电话格式归一:带国家码与不带国家码时,号码本体都取同一组号
- 版本号与时间戳混排:不同前缀形态下把数值部分统一取出
- 搭配条件匹配使用:条件里引用的组号在各分支下含义一致,避免逻辑分叉
- 减少取值分支:调用方只写一套 group(1)、group(2),无需判断命中了哪个分支
分支重置写法示例
分支重置写法示例
(?|(\d{4})-(\d{2})-(\d{2})|(\d{2})/(\d{2})/(\d{4})) # 年月日共用 1、2、3 号组
# 直接交替的对照写法:第二分支会从 4 号组开始,取值得写两套
(?:(\d{4})-(\d{2})-(\d{2})|(\d{2})/(\d{2})/(\d{4}))
(?|(?:\+86)?(1\d{10})|(?:\+1)?(\d{10})) # 号码本体共用 1 号组
(?|(?<v>a)|(?<v>b)) # 同名组需引擎允许重复名,以文档为准直接交替与分支重置对照
| 对比项 | 直接交替 | 分支重置 (?|…) |
|---|---|---|
| 组号分配 | 各分支顺延,整体偏移 | 各分支从同一起点重新编号 |
| 取值代码 | 需按分支分别取值 | 一套取值逻辑覆盖全部分支 |
| 分支增删 | 组号整体漂移,易出错 | 影响局限在该组内 |
| 可读性 | 分支多时组号难追踪 | 同位置字段一眼对应 |
组号共享的代价是无法从组号判断命中哪个分支:需要区分时,可在分支里再加一个标记性的捕获组,或先用外层捕获判定形态,不要靠组内容去猜。
在不同分支里使用同名组是否合法由引擎决定,部分引擎默认禁止重复组名,只允许在分支重置内出现,配置选项也能改变这一行为,书写前以目标引擎官方文档为准。