JS正则断言初探

3,605 阅读2分钟

正则断言

正向先行断言

reg为: (?=pattern)

'wink'.match(/w(?=ink)/g) // ["w"]

意为:匹配w且后面跟着ink的结果

正向后行断言

reg为: (?<=pattern)

'winkwink'.match(/(?<=ink)w/g) // ["w"]

意为:匹配ww前面跟着ink的结果

突发奇想

此处为本文重点!

正向后行断言的例子是这样的:

例如,“(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中
的"Windows",但不能匹配"3.1Windows"中的"Windows"

请看此处demo:

'123456789'.match(/(?<=7)\d+/g) // ["89"]

此处要是把(?<=7)放在匹配的结果前 结果一看就懂 要是把其放在需要匹配的结果之后呢?

'123456789'.match(/\d+(?<=7)/g) // ["1234567"]

是不是很奇怪 为什么这里会匹配到 ["1234567"] 我们可以尝试下面的例子:

'123456789'.replace(/(?<=7)/g, ',') // "1234567,89"

会发现,的位置是在7之后,原因是:

先行/后行断言 只是匹配到指定的位置 类似于^ $ \b \B

在此前提下,又因为\d+,所以从1匹配到号的位置。

负向先行断言

reg为: (?!pattern)

'wink~'.match(/~(?!ink)/g) // ["~"]

意为:匹配~且后面不允许有ink的结果

若将 (?!ink)放置在~前面,如下:

'wink~'.match(/(?!ink)~/g) // ['~']

**需要注意的是:**虽然上面两个的结果相同但是匹配顺序是不同的。

第一个: 先找到~再预测其后面有没有ink

第二个: 先找到没有ink的位置,再匹配~符号

负向后行断言

reg为: (?<!pattern)

`'wink~'.match(/(?<!ink)~/g)` // null

意为:匹配~且其前面不能有ink的结果


引出我写这篇文章的正则是下面这个:

/\B(?=(\d{3})+(?!\d))/g

一道面试题,大家应该都已经见过了,将123456789转化为123,456,789

解析:

  1. \B 获取非单词边界
  2. (?=(\d{3})+) 正向先行断言 匹配1次或多次 三个连续字符的位置
  3. (?!\d) 正向后行断言 后面字符不能为数字

参考

www.jb51.net/tools/regex…

若有错误请各位指出!