正则表达:负面观察与否定之间的区别

时间:2011-09-02 09:39:20

标签: regex lookbehind negative-lookbehind

来自regular-expressions.info

  

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

你能解释一下原因吗?

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

2 个答案:

答案 0 :(得分:7)

\b是零宽度断言,表示word boundary。这些字符位置(取自该链接)被视为字边界:

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

单词字符当然是\ws是单词字符,但'不是。在上面的示例中,'s之间的区域是单词边界。

如果我突出显示锚点和边界(第一个和最后一个"Jon's"出现在与\b^相同的位置),则字符串$如下所示: ^Jon\b'\bs$

负面后瞻断言(?<!s)\b意味着只有在字符s 之前没有字符边界时才会匹配字边界(即最后一个字符不是{{} 1}})。因此它在一定条件下寻找单词边界。

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

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

  2. 如上所示,nn之间实际上有另一个字边界,因此'匹配此字边界,因为它前面有一个{ {1}},而不是(?<!s)\b

  3. 由于已达到模式的结尾,因此结果匹配为n

  4. 互补字符类s表示它将匹配任何不是字母Jon 的字符,后跟字边界。与上面不同,它会查找一个字符,后跟一个单词边界。

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

    1. [^s]\b匹配前三个字母s \b\w+ J

    2. 由于o不是字母n(它符合字符类'),后面跟着一个字边界(在s之间) [^s]),它匹配。

    3. 由于已到达模式的结尾,因此结果匹配为'。字母s 匹配,因为它之前的单词边界已经匹配。

答案 1 :(得分:1)

该示例试图证明前瞻和后瞻可以用于创建“和”条件。


\b\w+(?<!s)\b

也可以写成

\b\w*\w(?<!s)\b

这给了我们

\b\w*[^s]\b    vs    \b\w*\w(?<!s)\b

我这样做,所以我们可以忽略不相关的。 (\b只是这个例子中的干扰。)我们有

[^s]    vs    \w(?<!s)

在左侧,我们可以匹配除“s”

之外的任何字符

在右侧,我们可以匹配除“s”

之外的任何字符

顺便说一下,

\w(?<!s)

也可以写

(?!s)\w      # Not followed by "s" and followed by \w