3

来自正则表达式.info

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

你能解释一下为什么吗?

另外,您能否说明一下究竟是做什么\b的,以及为什么它在撇号和 ? 之间匹配s

4

2 回答 2

7

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

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

word 字符当然是 any \ws是一个单词字符,但'不是。在上面的例子中,the'和 the之间的区域s是一个单词边界。

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

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

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

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

  2. 如上所示,nand之间实际上还有另一个单词边界,因此匹配这个单词边界,因为它前面是 an ,而不是 an 。'(?<!s)\bns

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

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

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

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

  2. 由于 the'不是字母s(它满足字符类[^s]),并且后面跟着一个单词边界(在'and之间s),所以它是匹配的。

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

于 2011-09-02T09:48:47.517 回答
1

The example is trying to demonstrate that lookaheads and lookbehinds can be used to create "and" conditions.


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

could also be written as

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

That gives us

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

I did that so we can ignore the irrelevant. (The \b are simply distractions in this example.) We have

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

On the left, we can match any character except "s"

On the right, we can match any word character except "s"

By the way,

\w(?<!s)

could also be written

(?!s)\w      # Not followed by "s" and followed by \w
于 2011-09-02T10:26:36.617 回答