正则零宽断言的理解
正则匹配中,除了文本的匹配外,还有位置匹配。
因为位置匹配不会匹配任何实际的文本,只是匹配文本中的位置,所以也称为锚点(Anchors)、零长度断言 或者 零宽断言 (Zero-Width Assertions)。
结合这几个名字,这个概念的含义已经很明显。
零宽断言是一种零宽度的匹配,它匹配的内容不会保存到匹配结果中,也不会占用index宽度,最终匹配的结果只是一个位置
简单的说,它用于查找在某些内容之前或之后的东西(但返回结果并不包括这些内容)
JavaScript提供了如下的零宽断言:
零宽断言 意义
^ 匹配输入的开始。
$ 匹配输入的结束。
\b 匹配一个词的边界。
\B 匹配一个非单词边界。
(?=p) 肯定顺序环视
(?!p) 否定顺序环视
(?<=p) 肯定逆序环视
(?<!p) 否定逆序环视
js的负向零宽断言是ES2018才支持的,同时支持的还有,命名分组和dotAll(.能匹配换行符)
Lookbehind assertion: (?<=...), (?<!...) (负向零宽断言) chrome 62 safari 16.4
function getPrice(label) { return /(?<=\$)\d+(?:\.\d*)?/.exec(label)?.[0]; } getPrice("$10.53"); // "10.53" getPrice("10.53"); // undefined
safari又拉胯,对于要兼容safari的情况,可以使用折中方案
1. 字符串和正则同时反转,然后匹配
2. 使用前置可空组判断(推荐,看起来简单一些)
前端匹配的字符串用一个组保存,通过判断这个组是否存在来处理
匹配所有前面不是ba的ll
var newString = "Fall ball bill balll llama".replace(/(ba)?ll/g, function($0,$1){ return $1 ? $0 : "[match]";}); // Fa[match] ball bi[match] balll [match]ama
ES2018同时支持的还有,命名分组和dotAll(.能匹配换行符)
Named capture groups(命名分组捕获) chrome 64 safari 11.1
const t = '2020-01-23'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
console.log(t.groups.year)
console.log(t.groups.month)
console.log(t.groups.day)
参考: