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/stage/3/proposal-regexp-buffer-boundaries.md.
  • 简体中文
  • RegExp Buffer Boundaries (\A, \z, \Z) S3

    中文标题:RegExp 缓冲区边界(\A, \z, \Z)

    提案概览
    提案速览

    该提案为 Unicode 模式的正则表达式引入了 \A、\z 和 \Z 字符转义,提供了缓冲区边界,可匹配整个输入的开头/结尾,而不受多行(m)标志的影响。这些转义提供了比现有模拟更易读、更可移植的替代方案,并被定义为基于修饰符的模式的同义词。

    Note

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

    ECMAScript 的正则表达式缓冲区边界

    本提案旨在为 Unicode 模式的正则表达式引入 \A\z\Z 字符转义,作为 (?-m:^)(?-m:$)(?=(?:\r\n|\n|\r|\u2028|\u2029)?(?-m:$)) 的同义词。

    状态

    阶段: 3
    提案负责人: Ron Buckton (@rbuckton)

    关于本提案的详细状态,请参阅下面的 TODO

    作者

    动机

    注意:请参阅 https://github.com/rbuckton/proposal-regexp-features 了解本提案如何融入正则表达式未来可能的功能中。

    缓冲区边界是各种正则表达式引擎中常见的功能,它允许你匹配整个输入的开头或结尾,而无需考虑是否设置了 m(多行)标志。缓冲区边界还允许你在单个正则表达式中使用 m 标志同时匹配行的开头/结尾以及输入的开头/结尾。

    虽然可以使用现有模式模拟 \A\z\Z,但替代方案更难阅读,并且需要对正则表达式有更全面的理解才能解释。

    例如,比较以下方法:

    // 在 `m` 模式之外模拟 `m` 模式下的 `^`:
    const a = /^foo|(?<=^|[\u000A\u000D\u2028\u2029])bar/u;
    
    // 在 `m` 模式下使用修饰符(提议)模拟非 `m` 模式下的 `^`:
    const b = /(?-m:^)foo|^bar/mu;
    
    // 使用 `\A`:
    const c = /\Afoo|^bar/mu;

    在上述示例中,读者不太可能轻松理解示例 (a) 中的表达式。不仅正则表达式的内容更难阅读,理解其目的还需要解释正则表达式的种不同功能如何交互:分组、正向后行断言、^ 元字符、析取、字符类和 Unicode 转义。

    示例 (b) 有所改进,但仍需要读者在视觉上平衡括号,并理解四种不同正则表达式功能的交互:分组、修饰符(提议)、m 标志和 ^ 元字符。

    相比之下,示例 (c) 更容易阅读。它包含一个简短的转义序列,仅由两个字符(\A)组成,这使得它更容易区分特殊模式语法和像 foobar 这样的纯文本段。

    \A\z\Z 转义在多种其他语言和正则表达式引擎中得到广泛支持。因此,它拥有大量现有的在线文档,包括 Wikipedia、众多教程网站以及其他语言的文档。这大大降低了学习 \A 相对于其替代方案的难度。

    与 RegExp 修饰符的关系

    本提案可以被视为 RegExp 修饰符(第 4 阶段)的语法糖:

    • \A(?-m:^)
    • \z(?-m:$)
    • \Z(?=(?:\r\n|\n|\r|\u2028|\u2029)?(?-m:$))

    虽然 RegExp 修饰符可以完成此任务,但 \A\z\Z 转义在多种不同语言中方便且可移植,并且经常出现在 JSON 和 YAML 等与语言无关的资源中,这些资源通常被构建工具和编辑器(例如 TextMate 语法文件)使用,并且经常被 ECMAScript 应用程序消费。因此,为这种行为引入一致的语法可以提高可移植性,并允许更多地重用网上的文档以及 LLM 和编码代理生成的源代码中的正则表达式模式。

    现有实践

    更多信息请参阅 https://rbuckton.github.io/regexp-features/features/buffer-boundaries.html。

    语法

    缓冲区边界类似于 ^$ 锚点,不同之处在于它们不受 m(多行)标志的影响:

    • \A — 匹配输入的开头。
    • \z — 匹配输入的结尾。
    • \Z — 一个零宽断言,由缓冲区末尾可选的换行符序列组成。
      • 当使用提议的 \R 转义序列1时,等同于 (?=\R?\z)
    NOTE

    需要 uv2 标志,因为在 uv 标志之外,附录 B\A\z\Z 视为 SourceCharacterIdentityEscape 序列,并表示字面字符 AzZ

    NOTE

    在字符类中不受支持。

    NOTE

    自 2021 年 12 月 15 日起,\Z 断言不再作为本提案的一部分考虑,但已保留以供将来可能使用。

    NOTE

    自 2026 年 5 月全体会议起,\Z 断言再次被采纳并推进至第 2.7 阶段。

    示例

    // 不使用缓冲区边界
    const re1 = /^foo$/u;
    re1.test("foo"); // true
    re1.test("foo\nbar"); // false
    
    const re2 = /^foo$/um;
    re2.test("foo"); // true
    re2.test("foo\nbar"); // true
    
    // 使用修饰符
    const re3 = /(?-m:^)foo(?-m:$)/um;
    re3.test("foo"); // true
    re3.test("foo\nbar"); // false
    // 使用缓冲区边界
    const re1 = /\Afoo\z/u;
    re1.test("foo"); // true
    re1.test("foo\nbar"); // false
    
    const re2 = /\Afoo\z/um;
    re2.test("foo"); // true
    re2.test("foo\nbar"); // false
    
    // 混合使用缓冲区边界和锚点
    const re = /\Afoo|^bar$|baz\z/um;
    re.test("foo");         // true
    re.test("foo\n");       // true
    re.test("\nfoo");       // false
    
    re.test("bar");         // true
    re.test("bar\n");       // true
    re.test("\nbar");       // true
    
    re.test("baz");         // true
    re.test("baz\n");       // false
    re.test("\nbaz");       // true
    // 匹配缓冲区末尾的换行符序列
    const re = /end\Z/;
    re.test("The end"); // true
    re.test("The end\n"); // true
    re.test("The end\r\n"); // true
    re.test("The end\u2028"); // true
    re.test("The end\n...or is it?"); // false

    历史记录

    • 2021 年 10 月 28 日 — 提议进入第 1 阶段(幻灯片
      • 结果:推进至第 1 阶段
    • 2021 年 12 月 15 日 — 提议进入第 2 阶段(幻灯片
      • 结果:\A\z 推进至第 2 阶段(\Z 未推进,但将被保留)
      • 第 2 阶段评审人:Richard Gibson、Waldemar Horwat
    • 2026 年 3 月 10 日 — 作为迟到的议程项目提议进入第 2.7 阶段(幻灯片
      • 因审查时间不足而受阻
      • 其他方面普遍持积极态度
      • 将在 2026 年 5 月重新提交至全体会议
    • 2026 年 5 月 19 日 — 重新引入 \Z 并提议进入第 2.7 阶段(幻灯片
      • \Z 的规范文本审核通过后,有条件地推进至第 2.7 阶段。
      • 达成共识重新引入 \Z
    • 2026 年 5 月 21 日 — 提议推进至第 3 阶段
      • 推进至第 3 阶段

    TODO

    以下是通过 TC39 提案流程 每个阶段所需完成的高层任务列表:

    第 1 阶段准入标准

    • 确定一位“提案负责人”来推进该添加。
    • 概述问题或需求以及解决方案大致形态的描述
    • 说明性示例
    • 高级 API

    第 2 阶段准入标准

    第 2.7 阶段准入标准

    • 完整规范文本
    • 指定的评审人已签署当前规范文本:
      • Richard Gibson (#5)
      • Waldemar Horwat (#4)
      • Chris de Almeida
    • ECMAScript 编辑器已签署当前规范文本。

    第 3 阶段准入标准

    第 4 阶段准入标准

    Footnotes

    1. 有关 \R 转义序列的更多信息,请参阅 https://github.com/tc39/proposal-regexp-r-escape。

    2. 有关 v 标志的更多信息,请参阅 https://github.com/tc39/proposal-regexp-set-notation。