为什么\ B工作但不是\ b

Ani*_*dha 1 .net javascript java regex

想要匹配一个以喜欢结尾的#

你好# 世界#

我试图使用边界

\b\w+#\b
Run Code Online (Sandbox Code Playgroud)

并且它不匹配.我认为这\b是一个非单词边界,但从这种情况来看似乎并非如此


出奇

\b\w+#\B
Run Code Online (Sandbox Code Playgroud)

火柴!

那么为什么在\B这里工作而不是\b!为什么\b在这种情况下不起作用!


注意: 是的,我们可以使用,\b\w+#(?=\s|$)但我想知道为什么\B在这种情况下有效!

nha*_*tdh 6

词边界的定义 \b

在单词中定义单词边界是不精确的.让我用前瞻,后和短手字符类来定义单词边界\w.

单词边界\b相当于:

(?:(?<!\w)(?=\w)|(?<=\w)(?!\w))
Run Code Online (Sandbox Code Playgroud)

意思是:

  • 正前方,有(至少)一个字符,一个字符,而正后方,我们找不到一个字字符(无论是字符不是单词字符,或者它是字符串的开始).

    要么

  • 右的背后,有(至少)一个字符,一个字符,而正前方,我们找不到一个字字符(或者字符不是单词字符,或者它是字符串的结尾).

(注意这与XOR扩展为连接和分离有多相似)

非字边界\B相当于:

(?:(?<!\w)(?!\w)|(?<=\w)(?=\w))
Run Code Online (Sandbox Code Playgroud)

意思是:

  • 在前面和后面,我们找不到任何单词字符.请注意,在此定义下,空字符串被视为非字边界.

    要么

  • 在前面和后面,双方都是文字.请注意,此分支需要2个字符,即不能出现在非空字符串的开头或结尾.

(注意这与XNOR扩展为连接和分离有多相似).

单词字符的定义 \w

由于定义\b\B依赖于\w1的定义,您需要查阅特定文档以确切知道\w匹配的内容.

1大多数正则表达式都\b基于\w.好吧,除了Java [Point 9],默认模式下,它\w只是ASCII,并且\b部分支持Unicode.

回答问题

根据上面的定义,回答问题变得容易:

"hi hello# world#"
Run Code Online (Sandbox Code Playgroud)

hello#,之后#是空格(U + 0020,在Zs类别中),它不是单词字符,并且#不是单词字符本身(在Unicode中,它在Po类别中).因此,\B可以在这里匹配.(?<!\w)(?!\w)在这种情况下使用分支.

world#,#字符串结尾之后.由于#不是单词字符,我们找不到前面的任何字符(没有任何内容),\B可以匹配后面的空字符串#.(?<!\w)(?!\w)在这种情况下也使用分支.

附录

Alan Moore在评论中给出了相当不错的总结:

我认为要记住的关键点是正则表达式无法读取.也就是说,他们不会用文字来处理,只能用字符来处理.当我们说\b匹配单词的开头或结尾时,我们并不是说它识别一个单词然后找出它的终点,就像人类一样.它只能看到当前位置的字符和当前位置的字符.因此,\b仅表示当前位置可以是单词边界.你要确保两边的角色应该是什么样的.


Aym*_*adi 5

英镑#符号不被视为"单词边界".

\b\w+#\b不起作用,因为w+#不被认为是一个单词,因此它不匹配world#.
\b\w+6\b在另一方面,因此它匹配world6.

"单词字符"定义如下:[A-Za-z0-9_].

简单地说:\b允许您使用正则表达式执行"仅限整个单词"搜索\bword\b."单词字符"是可用于形成单词的字符.所有不是"单词字符"的字符都是"非单词字符".

- http://www.regular-expressions.info/wordboundaries.html