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-regexp-lookbehind.md.
  • 简体中文
  • RegExp Lookbehind Assertions S4

    中文标题:正则表达式后行断言

    提案概览
    提案速览

    该提案为 ECMAScript 正则表达式添加了后行断言,允许模式基于前面的内容进行匹配而不消耗字符。它包含正向后行断言和负向后行断言两种形式,支持无限模式以及反转的匹配顺序。

    Note

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

    正则表达式后行断言

    作者:Gorkem Yakin、Nozomu Katō、Daniel Ehrenberg

    阶段 4

    简介

    环视是零宽断言,用于匹配字符串而不消耗任何字符。ECMAScript 已有前向断言(lookahead),但缺少向后匹配的方式,而后行断言(lookbehind)提供了这一能力。通过后行断言,可以确保一个模式前面是否出现另一个模式,例如匹配美元金额而不捕获美元符号。

    高级 API

    后行断言有两种形式:正向后行断言和负向后行断言。

    正向后行断言用 (?<=...) 表示,它确保括号内的模式出现在断言后面的模式之前。例如,如果想匹配美元金额而不捕获美元符号,可以使用 /(?<=\$)\d+(\.\d*)?/,这会匹配 '$10.53' 并返回 '10.53'。然而,它不会匹配 €10.53

    负向后行断言用 (?<!...) 表示,它确保括号内的模式不会出现在断言后面的模式之前。例如,/(?<!\$)\d+(?:\.\d*)/ 不会匹配 '$10.53',但会匹配 '€10.53'

    所有正则表达式模式,甚至是无限重复的模式,都允许作为后行断言的一部分。因此,可以编写 /(?<=\$\d+\.)\d+/ 来匹配美元金额并只捕获小数部分。

    通常,模式匹配从最左边的子模式开始,如果左边子模式成功,则向右继续。当在断言中时,匹配顺序会反转。模式从最右边的子模式开始匹配,并向左推进。例如,给定 /(?<=\$\d+\.)\d+/,模式会先找到一个数字,然后确保它前面是 .(向后匹配),接着从 . 开始匹配 \d+,最后从断言内 \d+ 开始的位置匹配 $。由于这个反转,回溯方向也会反转。

    细节

    在后行断言中,匹配语义是向后进行的——断言内的正则表达式片段被反转,字符串从后向前遍历。这对语义有几个影响。

    早期提案是禁止在断言内使用无限重复。Perl 使用这种更受限的语义。然而,如果细节以特定方式确定下来,似乎可以实现支持无限重复的更广泛语义。V8 中已经有采用这种语义的草稿实现。

    贪婪性从右到左

    首先,如果在断言内的捕获组中包含贪婪量词的子模式,其捕获的值与在断言外时不同。在断言内时,右侧的组捕获最多的字符,而不是左侧的组。例如,给定 /(?<=(\d+)(\d+))$/ 和字符串 '1053',第二个组捕获 '053',第一个组捕获 '1'。而使用 /^(\d+)(\d+)/ 时,第一个组捕获 '105',第二个组捕获 '3'

    捕获组编号

    在断言内,捕获组按从左到右的顺序编号。在示例 /(?<=(\d+)(\d+))$/ 匹配字符串 '1053' 时,match[1]"1"match[2]"053"

    引用捕获组

    在断言内,只能引用已经求值的捕获组。也就是说,该组必须位于引用的右侧。例如,/(?<=(.)\1)/ 不是很有用的正则表达式,因为 \1 无法解析,会匹配空字符串。相反,要查找前面两个相同字母,可以写 /(?<=\1(.))/

    负向断言

    类似于 ECMAScript 正则中长期存在的负向前瞻断言 /(?!.)/,该提案包含负向后行断言 /(?<!.)/

    规范草案

    由 Thomas Wood 和 Claude Pache 编写的规范片段

    实现