正则表达:负面观察和否定之间的差异

Ben*_*ier 3 regex negative-lookbehind lookbehind

来自regular-expressions.info:

\b\w+(?<!s)\b.这绝对不一样\b\w+[^s]\b.适用时Jon's,前者将匹配Jon后者Jon'(包括撇号).我会留给你弄清楚原因.(提示:\ b匹配撇号和s).后者也不会匹配像"a"或"I"这样的单字母单词.

你能解释一下原因吗?

此外,你能说清楚exacly \b做了什么,以及为什么它在撇号和s?之间匹配?

Bol*_*ock 7

\b是零宽度断言,意味着字边界.这些字符位置(取自该链接)被视为字边界:

  • 在字符串中的第一个字符之前,如果第一个字符是单词字符.
  • 在字符串中的最后一个字符之后,如果最后一个字符是单词字符.
  • 在字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符.

单词字符当然是任何字符\w.s是一个单词字符,但'不是.在上面的例子中,之间的区域's是一个字边界.

该字符串"Jon's"看起来是这样的,如果我想强调的锚和边界(第一和最后一个\b小号出现在为相同的位置^$):^Jon\b'\bs$

否定的lookbehind断言(?<!s)\b意味着它只会匹配一个单词边界,如果它没有前面的字母s(即最后一个单词不是a s).因此它在一定条件下寻找单词边界.

因此第一个正则表达式的工作原理如下:

  1. \b\w+匹配前三个字母J o n.

  2. 实际上还有另一个单词边界n,'如上所示,所以(?<!s)\b匹配这个单词边界,因为它前面有一个n,而不是一个s.

  3. 由于已到达模式的结尾,因此得到的匹配是Jon.

互补字符类[^s]\b意味着它将匹配任何不是字母的字符s,后跟字边界.与上面不同,它查找一个字符后跟一个单词边界.

因此第二个正则表达式的工作原理如下:

  1. \b\w+匹配前三个字母J o n.

  2. 因为'它不是字母s(它满足字符类[^s]),后面是字边界(在'和之间s),它是匹配的.

  3. 由于已到达模式的结尾,因此得到的匹配是Jon'.这封信s匹配的,因为之前的字边界已经匹配.