For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/proposal-duplicate-named-capturing-groups.md.
  • 简体中文
  • Duplicate named capture groups S4

    中文标题:重复命名捕获组

    提案概览
    提案速览

    此提案解决了 JavaScript 正则中命名捕获组必须唯一的问题,该限制阻止在不同分支中重用相同名称。它允许在不同可选分支中重复使用组名,反向引用和 groups 对象引用实际参与匹配的组。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    此提案已被接受,并已合入规范。历史实现跟踪请参见此问题。进一步的问题应遵循常规贡献流程

    原始 README 如下。

    重复命名捕获组

    目前,在 JavaScript 中,正则表达式中的命名捕获组必须是唯一的。因此

    str.match(/(?<year>[0-9]{4})-[0-9]{2}|[0-9]{2}-(?<year>[0-9]{4})/)

    会报错,因为你重用了 year 组名。但有时你想要匹配可以以多种格式编写的内容(如上所示)。在这种情况下,能够使用相同的组名会很好。

    状态

    此提案在 2024 年 4 月的会议 上达到了第 4 阶段。

    规范文本

    参见此 PR。规范文本应已完备。

    测试

    Test262 测试可在以下位置获取:

    细节

    重复名称必须位于不同的可选分支中

    目前,此提案仅允许在不同 | 分支中重复使用名称,这样单个匹配不可能真正多次使用同一个名称。如果你有在单个分支内重复使用名称的用例,请开启一个问题。请注意,这将使语义变得更加复杂。

    反向引用

    随着此更改,可能出现一个反向引用可能引用多个不同组的情况,如

    /(?:(?<a>x)|(?<a>y))\k<a>/

    然而,上述限制意味着最多只有一个组能够实际参与匹配。*

    因此,实际上最多只有一个组会匹配。此提案规定,反向引用引用实际参与匹配的那个组。在没有组匹配的情况下,它无条件地匹配而不消耗任何输入(这已是当前的工作方式)。

    *从技术上讲,在重复(+, *, {2} 等)的多次迭代中,可能有不同的组参与匹配,但已经明确,只有最后一次迭代对反向引用“有效”。

    groups 对象

    与反向引用类似,匹配结果中 groups 对象的相应命名属性引用实际参与匹配的那个组。

    对于属性枚举顺序,这些命名属性按它们在正则表达式中出现的顺序创建,无论哪些组实际参与了匹配。

    你能_引用_不同分支中的组吗?

    考虑

    /(?<a>x)|\k<a>/

    这个反向引用从未有用,因为它引用的组位于不同的分支中。因此,它的行为是始终匹配而不消耗任何输入。(这很奇怪,但对于 \1 风格的匹配也是如此。)即使在重复中也是如此,因为重复部分内的捕获组在每次迭代开始时被清除。因此,没有理由编写这样的代码。

    不幸的是,它目前是合法的。此提案不会改变这一点。

    其他语言

    根据此网页,多种语言允许重复名称,尽管语义略有不同。我相信将限制在不同分支中的组上,使此提案处于它们语义的交集。

    之前的讨论

    参见此问题以及twitter 上的一些讨论