后行断言:(?<=...), (?<!...)
后行断言“向后看”:它尝试将给定模式与之前的输入进行匹配,但它不消耗任何输入——如果匹配成功,输入中的当前位置保持不变。它以相反的顺序匹配其模式中的每个原子。
语法
正则表达式
(?<=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® 2026 语言规范 # prod-Assertion |
浏览器兼容性
加载中…