正则表达式中\ b和\ B的区别


103

我正在阅读有关正则表达式的书,并且遇到了以下示例\b

猫把食物撒在整个房间里。

使用正则表达式- \bcat\b将匹配单词,cat但不匹配catin scattered

对于\B作者使用以下示例:

请输入9位数的ID

出现在您的颜色-编码的密码钥匙上。

在单词之间使用正则表达式\B-\B匹配。使用在另一方面相匹配的中和。-color - coded\b-\b-nine-digitpass-key

为什么在我们使用的第一个例子中\b分离cat,并在第二次使用\B分离-?使用\b在第二个例子做什么它做前面相反。

请给我解释一下区别。

编辑:另外,任何人都可以用一个新的例子进行解释吗?

Answers:


84

混淆源于您的思维\b匹配空间(可能是因为“ b”表示“空白”)。

\b匹配单词开头或结尾的空字符串。 \B匹配空字符串,而不是单词的开头或结尾。这里的关键是“-”不是单词的一部分。如此<left>-<right>匹配\b-\b是因为的任意一侧都存在单词边界-。另一方面<left> - <right>(请注意空格),破折号的两边都没有单词边界。单词边界是向左和向右进一步的一个空格。

另一方面,在搜索\bcat\b单词边界时,行为更直观,并且符合预期的“ cat”匹配。


2
是的,我确实确实将\ b与空格混淆了。但是,我仍然感到有些困惑。我可以再问一个例子吗?
2011年

3
关键是-不能将其视为单词的一部分。同样,!不是单词的一部分。因此,再次\b!\b匹配“ uunet!iamold”,但不匹配“ Wow!You are”。您可以在regexpal.com上尝试一下
andrewdski

@andrewdski在我的情况下,\ b也抓取了标点符号…我在1987894,3219800上尝试使用\ b [A-Z0-9] + \ b;234567,345261。它工作正常,我只获得数字
gunzapper 2014年

1
只需补充一下,正则表达式中的作品是由字母(az和AZ),数字和“ _”(下划线)组成的。其他一切都是言语。
Maralc

有人可以详细说明这条线\B matches the empty string not at the beginning or end of a word
吗?

68

\b是零宽度的字边界。特别:

在单词字符(任何与\ w匹配的字符)和非单词字符(任何与[^ \ w]或\ W匹配的字符)之间的位置以及字符串的开头和/或结尾处匹配和/或字符串中的最后一个字符是单词字符。

例如:.\b比赛cabc

\B是零宽度的非单词边界。特别:

匹配两个单词字符之间的位置(即\ w \ w之间的位置)以及两个非单词字符之间的位置(即\ W \ W)。

例如:\B.\B比赛babc

有关更多重要的正则表达式信息,请参见regular-expressions.info


10
+1是因为零宽度是定义的重要组成部分。如果宽度不是零,那么它还将在模式的匹配部分中抓住那些单词/非单词字符。
本·霍金

5
换句话说,\ B匹配\ W和\ W之间或\ w和\ w之间的点,但不匹配\ W和\ w之间的点。

1
该答案已添加到“锚定”下的堆栈溢出正则表达式常见问题解答中
aliteralmind 2014年

1
@stephenhuh string.match()只返回了第一场比赛,除非你加入全球标志g"abc def".match(/\b./g)回报['a', ' ', 'd']
波西米亚

1
我认为这是更好的答案。我也应该被接受,因为它解决了混乱。在这里可以学到更多。

38

换一个例子:

考虑这是要搜索的字符串和模式为“ cat”:

text = "catmania thiscat thiscatmaina";

现在定义

'\ b'查找/匹配每个单词开头或结尾的模式。

'\ B'在每个单词的开头或结尾找不到/匹配模式。

不同情况:

情况1:每个单词的开头

result = text.replace(/\bcat/g, "ct");

现在,结果是“ ctmania thiscat thiscatmaina”

情况2:每个单词的末尾

result = text.replace(/cat\b/g, "ct");

现在,结果是“ catmania thisct thiscatmaina”

情况3:不是一开始

result = text.replace(/\Bcat/g, "ct");

现在,结果是“ catmania thisct thisctmaina”

情况4:到最后

result = text.replace(/cat\B/g, "ct");

现在,结果是“ ctmania thiscat thisctmaina”

情况5:既不开始也不结束

result = text.replace(/\Bcat\B/g, "ct");

现在,结果是“ catmania thiscat thisctmaina”

希望这可以帮助 :)


请纠正我,如果我错了,但是,当使用\ bcat \ b时,如果我们的字符串是正确的,例如:“ catcat is my cat” =>第一个单词(catcat)将适用于这种情况。没有?。
Kosem

8

元字符\ b是锚号,如插入号和美元符号。它在称为“单词边界”的位置匹配。此匹配为零长度。

有三个不同的位置可以作为单词边界:

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

\ B是\ b的否定版本。\ B在\ b不匹配的每个位置匹配。实际上,\ B在两个单词字符之间的任何位置以及两个非单词字符之间的任何位置匹配。

资料来源:http : //www.regular-expressions.info/wordboundaries.html


3

\b匹配单词边界。\B匹配非单词边界,并且等效于(感谢@Alan Moore进行更正!)。两者都是零宽度。[^\b](?!\b)

有关详细信息,请参见http://www.regular-expressions.info/wordboundaries.html。该网站对于许多基本正则表达式问题非常有用。


4
\B不是等同于[^\b]。字符类([...][^...])消耗的一个字符,而零宽度断言像\b\B不消耗任何东西。如果放入\b字符类,则它具有完全不同的含义:[\b]匹配一个退格键,并且[^\b]匹配一个退格键之外的任何字符。 \B真的等价于(?!\b)
艾伦·摩尔

@Alan谢谢,您是完全正确的-今天早晨,当我写这封信时,我还没有醒着。固定。
马特·鲍尔,

4
...但是为什么有人要匹配一个退格键却超出了我。:D
艾伦·摩尔

1

让一个像这样的字符串:

XIX IXI XX XI II IIXX XXII II XX -X X- XI IX -X- -IX -XI IX- XI- X_X _X-

注意:在这种情况下,下划线(_)不被视为特殊字符。

  1. /\bX\b/g 应该以特殊字符或空白开头和结尾

XIX XX IXI X I II IIXX XXII II XX - X XX -I I- XX - -I- XX -I I- XX -I- X_X _X-


  1. /\bX/g 应该以特殊字符或空格开头

X IX IXI X X X I II IIXX X XII II X - X - X X - X -I IX - X - -I- X - X -I IX - X -I- X _X _X-


  1. /X\b/g 应该以特殊字符或空格结尾

十一X IXI X X X I II IIX X XXII II X - X - X X - X -I I- X - X - -I- X - X -I I- X - X -I- X_ X _ X -


  1. /\BX\B/g
    如果没有开始,以特殊字符或空格结尾

XIX I X I XX XI II II X X X X X II II XX -X X- XI IX -X- -IX -XI IX- XI- X_X _X-


  1. /\BX/g如果没有特殊字符或空格开始

XI XX我X X XI II II XX X X II II XX -X X- XI IX -IX -X- -XI IX-XI-X_ X _ X -


  1. /X\B/g如果没有特殊字符或空格结尾

X X IX I X I X X XI II II X X XX II II XX -X X- XI IX -X- -IX -XI IX- XI- X _X _X-


  1. /\bX\B/g应该以一个特殊字符或空白开头而不是结尾

X IX IXI X X XI II II X X X XII II XX -X X- XI IX -X- -IX -XI IX- XI- X _X _X-


  1. /\BX\b/g如果开始,应该用特殊字符或空格结尾

XI X IXI X X XI II IIX X XXII II XX -X X- XI IX -IX -X- -XI IX-XI-X_ X _ X -


1

资料来源 ©版权所有RexEgg.com

字边界:\ b *

单词边界\ b匹配的位置是一侧是单词字符(通常是字母,数字或下划线,但请参见下文了解不同的引擎),而另一侧不是单词字符(例如,它可能是单词的开头)字符串或空格字符)。

因此,正则表达式\ bcat \ b会与黑猫中的cat相匹配,但与catatonic,tomcat或证书中的相匹配。除去边界之一,\ bcat将匹配match鱼中的cat,而cat \ b将匹配tomcat中的cat,但反之则不然。当然,两者都会单独匹配cat。

非单词边界:\ B

\ B匹配\ b不匹配的所有位置。因此,它匹配:

✽当双方都不是单词字符时,例如在字符串$ =(@-%++)中的任何位置(包括字符串的开头和结尾)

both当双方都是文字字符时,例如H和i之间在Hi!

这似乎不太有用,但是有时\ B就是您想要的。例如,

B \ Bcat \ B会发现cat完全被单词字符包围,就像在证书中一样,但不能单独出现,也不能位于单词的开头或结尾。

✽cat \ B会在证书和cat鱼中找到猫,但在tomcat中或单独都不会找到。

B \ Bcat会在证书和tomcat中都找到猫,但在cat鱼中或单独都不会找到。

✽\ Bcat | cat \ B将在嵌入式情况下找到猫,例如在证书,cat鱼或tomcat中,但不是单独找到。


1

\ b用作单词边界

word = "categorical cat"

在上面的单词中找到所有的“猫”

没有\ b

re.findall(r'cat',word)
['cat', 'cat']

与\ b

re.findall(r'\bcat\b',word)
['cat']

0

\B不是 \b \b

pass-key这里没有单词边界,-所以它与\B您的第一个示例匹配。cat旁边有单词边界,因此它与您匹配\b

类似的规则也适用于其他人。\W是负\w \UPPER CASE是负\LOWER CASE

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.