用名字代替编号
命名分组给捕获组起一个标识符,读取时按名字取值,不再依赖括号顺序。模式里插入或删除分组时,取值代码不必跟着改,这是它在维护性上的最大价值。
写法并不统一
定义语法在各引擎中分两派,模式内的反向引用与替换串里的引用写法也各不相同。跨语言复用模式前先把这三处(定义、模式内引用、替换引用)逐一对照,避免只在某一处想当然。
基本信息
| 主要收益 | 取值按名字,模式调整时引用不易错位 |
|---|---|
| 定义语法差异 | 部分引擎在问号后写大写 P 加尖括号名字,其余引擎直接写问号加尖括号名字 |
| 模式内引用 | 各引擎写法不同,常见为反斜杠加 k 加名字或问号加大写 P 加等号加名字 |
| 替换引用 | 常见为反斜杠加 g 加尖括号名字、美元符号加尖括号名字、美元符号加花括号名字 |
| 命名规则 | 名字通常只允许字母数字与下划线,且不能以数字开头 |
| 唯一性 | 同一模式内名字一般不允许重复,具体规则以引擎文档为准 |
典型使用场景
- 解析结构化字段,按名字取出各段内容
- 替换中引用命名分组,替换串含义自明
- 同一模式被多处复用时,避免新增括号导致取值错位
- 在模式内引用命名分组做成对结构校验
- 给复杂模式的分段命名,顺带提升可读性
三种写法的对照
三种写法的对照
定义(部分引擎) (?P<year>\d{4}) 问号大写 P 加尖括号名字
定义(其余引擎) (?<year>\d{4}) 问号加尖括号名字
模式内引用 \k<year> 或 (?P=year)
替换引用 \g<year> 或 $<year> 或 ${year}
取值 Python group('year')
JS match.groups.year
Java matcher.group("year")
# 名字必须唯一且不能以数字开头命名分组的三个位置
| 位置 | 作用 | 注意点 |
|---|---|---|
| 定义处 | 给分组起名 | 两派语法不同,需按引擎选择 |
| 模式内引用 | 要求此处内容与已捕获内容相同 | 属反向引用,需引擎支持 |
| 替换与取值 | 按名字读取或写回 | 各语言接口名与写法不同 |
命名分组通常仍保留数字编号,两种读取方式可以并存。新代码优先用名字读取,能显著降低模式调整带来的连带修改。
部分实现允许重复名字并保留多次匹配结果,部分则明确禁止重名。写跨引擎模式时不要依赖重名特性,改为不同名字更安全。