【问题标题】:Difference between \b and \B in regex正则表达式中 \b 和 \B 之间的区别
【发布时间】:2011-10-03 14:19:38
【问题描述】:

我正在阅读一本关于正则表达式的书,我遇到了\b 的这个例子:

猫把他的食物撒了一地。

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

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

请输入九位数的身份证

出现在您的彩色密码密码上。

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

为什么在第一个示例中我们使用\b 分隔cat 而在第二个示例中使用\B 分隔-?在第二个示例中使用 \b 与之前所做的相反。

请解释一下区别。

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

【问题讨论】:

  • 你读什么书?也许可以帮助其他人学习正则表达式
  • @YohanesAI 这本书是 Sams 在 10 分钟内自学正则表达式,作者 Ben Forta

标签: regex


【解决方案1】:

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

\b 匹配单词开头或结尾处的空字符串\B 匹配不在单词开头或结尾的空字符串。这里的关键是“-”不是单词的一部分。所以<left>-<right> 匹配\b-\b,因为- 的两边都有单词边界。另一方面,对于<left> - <right>(注意空格),破折号的两侧没有单词边界。单词边界是左右各一个空格。

另一方面,在搜索 \bcat\b 时,单词边界表现得更直观,并且与预期的“cat”匹配。

【讨论】:

  • 是的,我确实将 \b 与空格混淆了。但是,我仍然感到有些困惑。我可以再问你一个例子吗?
  • 关键是-不被认为是单词的一部分。同样,! 不是单词的一部分。所以\b!\b 再次匹配“uunet!iamold”,但不匹配“哇!你是”。您可以在regexpal.com 试用这些东西。
  • @andrewdski 在我的情况下 \b 也捕获标点符号...我在 1987894、3219800 上尝试使用 \b[A-Z0-9]+\b; 234567、345261。它工作正常,我只获得数字
  • 只需添加正则表达式中的作品由字母(a-z 和 A-Z)、数字和“_”[下划线]组成。其他一切都是无言的。
  • 有人能详细说明这一行吗\B matches the empty string not at the beginning or end of a word
【解决方案2】:

\b 是一个零宽度字边界。具体来说:

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

示例:.\b 匹配 abc 中的 c

\B 是一个零宽度的非字边界。具体来说:

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

示例:\B.\B 匹配 b 中的 abc

请参阅regular-expressions.info 了解更多重要的正则表达式信息

【讨论】:

  • +1 因为零宽度是定义的重要部分。如果它不是零宽度,那么它也会在模式的匹配部分中抓取那些单词/非单词字符。
  • 换句话说,\B 匹配 \W 和 \W 之间或 \w 和 \w 之间的点,但不匹配 \W 和 \w 之间的点。
  • 此答案已添加到 Stack Overflow Regular Expression FAQ 的“锚点”下。
  • @stephenhuh string.match() 仅返回第一个匹配项,除非您添加 global 标志 g"abc def".match(/\b./g) 返回 ['a', ' ', 'd']
  • 我认为这是更好的答案。我也应该被接受,因为它解决了混乱。在这里可以学到更多。
【解决方案3】:

换个例子:

认为这是要搜索的字符串和模式是“猫”:

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 这是一个很好的问题,让我更好地学习\b。我之后的理解是第一个单词不匹配的原因是\bcat\b你说cat必须被单词边界包围。 catcat 以单词边界开头,找到第一个内部 cat [我们仍然尊重正则表达式],但尾部 \b 强加于 catcat 中的第一个 t 之后应该有另一个词边界,情况并非如此,因为catcat 中的第二个c 是另一个单词字符[= word继续]。跳过catcat 的第二个cat 的类似原因
【解决方案4】:

元字符 \b 是类似于插入符号和美元符号的锚。它在称为“单词边界”的位置匹配。这个匹配是零长度的。

有资格作为单词边界的三个不同位置:

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

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

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

【讨论】:

    【解决方案5】:

    \b 用作单词边界

    word = "categorical cat"
    

    找出以上单词中的所有“猫”

    没有\b

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

    与\b

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

    【讨论】:

      【解决方案6】:

      \b 匹配单词边界。 \B 匹配非单词边界,相当于 [^\b](?!\b) (感谢@Alan Moore 的更正!)子>。两者都是零宽度。

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

      【讨论】:

      • \B等同于[^\b]。一个字符类([...][^...])只消耗一个字符,而像\b\B 这样的零宽度断言不消耗任何东西。如果你把\b 放在一个字符类中,它的含义就完全不同了:[\b] 匹配一个退格,[^\b] 匹配任何字符除了一个退格。 \B 真的等同于 (?!\b)
      • @Alan 谢谢,你是完全正确的——我今天早上写这篇文章的时候还没醒。固定。
      • ...但是为什么有人想要匹配退格键是我无法理解的。 :D
      【解决方案7】:

      Source © 版权所有 RexEgg.com

      字边界:\b*

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

      因此,正则表达式 \bcat\b 会匹配黑猫中的 cat,但不会匹配 catatonic、tomcat 或证书中的 cat。删除其中一个边界,\bcat 将匹配 catfish 中的 cat,而 cat\b 将匹配 tomcat 中的 cat,但反之则不行。当然,两者都会单独匹配 cat。

      非单词边界:\B

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

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

      ✽当两边都是单词字符时,比如Hi中的H和i之间!

      这似乎不是很有用,但有时 \B 正是你想要的。例如,

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

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

      ✽ \Bcat 会在证书和 tomcat 中找到 cat,但不会在 catfish 中或单独找到。

      ✽ \Bcat|cat\B 会在嵌入的情况下找到 cat,例如在证书、catfish 或 tomcat 中,但不是单独的。

      【讨论】:

        【解决方案8】:

        让我们取一个像这样的字符串:

        XIX IXI XX X I II IIXX XXII I-I 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 IXI XX X I II IIXX XXII II X-X -X X- X-I I-X -X- -I-X -X -I I-X- X-I- X_X _X-


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

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


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

        XIX IXI XX X I II IIXX 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 IXI XX XI II IIXXXXII II XX -X X- XI IX -X- -IX - XI IX- XI- X_X _X-


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

        XIX IXIXX XI II IIXX XX II II XX -X X- XI IX -X- -IX -XI IX- XI- X_X _X-


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

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


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

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


        1. /\BX\b/g 应该以特殊字符或空格开始而结束

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

        【讨论】:

          【解决方案9】:

          \B不是 \b 例如否定 \b

          pass-key - 旁边没有单词边界,所以它匹配 \B 在你的第一个示例中,cat 旁边有单词边界,所以它匹配 \b

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

          【讨论】:

            猜你喜欢
            • 2013-06-05
            • 2020-06-12
            • 2015-02-21
            • 1970-01-01
            • 1970-01-01
            • 2021-05-20
            • 2017-09-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多