后视断言:(?<=...),(?<!...)

**后视断言**“向后查看”:它尝试使用给定模式匹配之前的输入,但它不消耗任何输入——如果匹配成功,输入中的当前位置保持不变。它以相反的顺序匹配其模式中的每个原子。

语法

正则表达式
(?<=pattern)
(?<!pattern)

参数

模式

由您可能在正则表达式字面量中使用的任何内容组成的模式,包括析取

描述

正则表达式通常从左到右匹配。这就是为什么前瞻和后视断言如此命名——前瞻断言右侧的内容,后视断言左侧的内容。

为了使 (?<=pattern) 断言成功,pattern 必须匹配当前位置左侧的输入,但在匹配后续输入之前,当前位置不会改变。(?<!pattern) 形式否定断言——如果 pattern 不匹配当前位置左侧的输入,则它成功。

后视通常与前瞻具有相同的语义——但是,在后视断言中,正则表达式向后匹配。例如,

js
/(?<=([ab]+)([bc]+))$/.exec("abc"); // ['', 'a', 'bc']
// Not ['', 'ab', 'c']

如果后视从左到右匹配,它应该首先贪婪地匹配 [ab]+,这使得第一组捕获 "ab",而剩余的 "c"[bc]+ 捕获。但是,由于 [bc]+ 首先匹配,它贪婪地获取 "bc",只留下 "a"[ab]+ 使用。

这种行为是合理的——匹配器不知道在哪里开始匹配(因为后视可能不是固定长度的),但它知道在哪里结束(在当前位置)。因此,它从当前位置开始并向后工作。(某些其他语言中的正则表达式禁止非固定长度的后视以避免此问题。)

对于后视内部的量化捕获组,由于向后匹配,因此捕获输入字符串最左侧的匹配——而不是右侧的匹配。有关更多信息,请参阅捕获组页面。反向引用在后视内部必须出现在它所引用的组的左侧,这也是由于向后匹配。但是,析取仍然是从左到右尝试的。

示例

匹配字符串而不消耗它们

前瞻类似,后视可用于匹配字符串而不消耗它们,以便仅提取有用的信息。例如,以下正则表达式匹配价格标签中的数字

js
function getPrice(label) {
  return /(?<=\$)\d+(?:\.\d*)?/.exec(label)?.[0];
}

getPrice("$10.53"); // "10.53"
getPrice("10.53"); // undefined

可以通过捕获您感兴趣的子匹配来实现类似的效果。

规范

规范
ECMAScript 语言规范
# prod-断言

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅