雁过留声

a tiger in me sniffs roses

0%

正则表达式中的断言

断言属于Group constructs,但是不匹配具体的东西,所以也被称为零宽断言。他们用来指定一个位置,为这个断言为真时才继续进行匹配。

捕获型匹配

(…) 匹配括号中的内容
(a|b) 匹配a或者b
(?<name>…), 同上但是为分组取一个名字,当分组很多时为分组取一个名字很有用。注:在golang,python中为(?P<name>...)
以上匹配都会占用匹配位置,并生成分组,正则表达式内可以通过\1,\2,\3 or \k<name> 来引用

1
"aabcab".match(/(a)\1/) //["aa", "a", index: 0, input: "aabcab", groups: undefined]

(?:…) 匹配…内容,和(…)一样。但是不捕获分组

1
"foobar".match(/foo(?:ab|bar)/) //["foobar", index: 0, input: "foobar", groups: undefined]

断言

  1. (?=…) 正向先行断言(positive lookahead)

当执行匹配时,当该断言表达式如果为真(positive),则匹配断言前面(lookahead)的内容。

1
2
3
4
/foo(?=bar)/.exec("foobar")
//["foo", index: 0, input: "foobar", groups: undefined]
/foo(?=bar)bar/.exec("foobar")
//["foobar", index: 0, input: "foobar", groups: undefined]
  1. (?<=…) 正向后发断言(positive lookbehind)

和前一个相反,当该断言表达式如果为真(positive),则匹配断言后边(lookbehind)的内容。注意断言表达式写在左边,从断言表达式往后看。

1
2
3
4
5
/(?<=foo)bar/.exec("foobar")
//["bar", index: 3, input: "foobar", groups: undefined]

/(?<=foo)bar/.exec("foubar")
//null
  1. (?!…) 负向先行断言 (negative lookahead)

当执行匹配时,当该断言表达式如果为假(negative),则匹配断言前面的内容。注意断言表达写在右边,即从断言表达式往前看。

1
2
3
4
5
/foo(?!bar)/.exec("foobar")
//null

/foo(?!bar)/.exec("foobaz")
//["foo", index: 0, input: "foobaz", groups: undefined]
  1. (?<!…) 负向后发断言 (negative lookbehind)

当执行匹配时,当该断言表达式如果为假(negative), 则匹配断言后面的内容。

1
2
3
4
5
/(?<!foo)bar/.exec("foobar")
//null

/(?<!foo)bar/.exec("farbar")
//["bar", index: 3, input: "farbar", groups: undefined]