Duplicate named capture groups S4
中文标题:重复命名捕获组
- 阶段: Stage 4
- 状态: 已完成
- ECMAScript 版本: ES2025
- 同步时间: 2026年8月26日
- English original · 官方仓库
此提案解决了 JavaScript 正则中命名捕获组必须唯一的问题,该限制阻止在不同分支中重用相同名称。它允许在不同可选分支中重复使用组名,反向引用和 groups 对象引用实际参与匹配的组。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
此提案已被接受,并已合入规范。历史实现跟踪请参见此问题。进一步的问题应遵循常规贡献流程。
原始 README 如下。
重复命名捕获组
目前,在 JavaScript 中,正则表达式中的命名捕获组必须是唯一的。因此
会报错,因为你重用了 year 组名。但有时你想要匹配可以以多种格式编写的内容(如上所示)。在这种情况下,能够使用相同的组名会很好。
状态
此提案在 2024 年 4 月的会议 上达到了第 4 阶段。
规范文本
参见此 PR。规范文本应已完备。
测试
Test262 测试可在以下位置获取:
- https://github.com/tc39/test262/pull/3625
- https://github.com/tc39/test262/pull/3706
- https://github.com/tc39/test262/pull/3709
细节
重复名称必须位于不同的可选分支中
目前,此提案仅允许在不同 | 分支中重复使用名称,这样单个匹配不可能真正多次使用同一个名称。如果你有在单个分支内重复使用名称的用例,请开启一个问题。请注意,这将使语义变得更加复杂。
反向引用
随着此更改,可能出现一个反向引用可能引用多个不同组的情况,如
然而,上述限制意味着最多只有一个组能够实际参与匹配。*
因此,实际上最多只有一个组会匹配。此提案规定,反向引用引用实际参与匹配的那个组。在没有组匹配的情况下,它无条件地匹配而不消耗任何输入(这已是当前的工作方式)。
*从技术上讲,在重复(+, *, {2} 等)的多次迭代中,可能有不同的组参与匹配,但已经明确,只有最后一次迭代对反向引用“有效”。
groups 对象
与反向引用类似,匹配结果中 groups 对象的相应命名属性引用实际参与匹配的那个组。
对于属性枚举顺序,这些命名属性按它们在正则表达式中出现的顺序创建,无论哪些组实际参与了匹配。
你能_引用_不同分支中的组吗?
考虑
这个反向引用从未有用,因为它引用的组位于不同的分支中。因此,它的行为是始终匹配而不消耗任何输入。(这很奇怪,但对于 \1 风格的匹配也是如此。)即使在重复中也是如此,因为重复部分内的捕获组在每次迭代开始时被清除。因此,没有理由编写这样的代码。
不幸的是,它目前是合法的。此提案不会改变这一点。
其他语言
根据此网页,多种语言允许重复名称,尽管语义略有不同。我相信将限制在不同分支中的组上,使此提案处于它们语义的交集。
之前的讨论
参见此问题以及twitter 上的一些讨论。