想要匹配以<{1}}结尾的字
你好你好# 世界#
我试图使用边界
#
并且它不匹配。我认为\b\w+#\b
是一个非单词边界但是从这种情况看起来并非如此
令人惊讶
\b
匹配!
那么为什么\b\w+#\B
在这里工作而不是\B
!为什么\b
在这种情况下不起作用!
注意:
是的,我们可以使用\b
,但我想知道为什么\b\w+#(?=\s|$)
适用于这种情况!
答案 0 :(得分:6)
\b
在单词中定义单词边界是不精确的。让我用 look-ahead , look-behind 和短手词字符类\w
来定义单词边界。
单词边界\b
相当于:
(?:(?<!\w)(?=\w)|(?<=\w)(?!\w))
这意味着:
在前面,(至少)一个字符是一个单词字符,和就在后面,我们找不到单词字符(要么字符不是单词字符,或者它是字符串的开头。)
或强>
(注意这与XOR扩展为连接和分离有多相似)
非字边界\B
相当于:
(?:(?<!\w)(?!\w)|(?<=\w)(?=\w))
这意味着:
在前方和后方,我们找不到任何单词字符。请注意,在此定义下,空字符串被视为非字边界。
或强>
(注意这与XNOR扩展为连接和分离有多相似)。
\w
由于\b
和\B
的定义取决于\w
1 的定义,因此您需要查阅具体文档以确切了解{{1}匹配。
1 大多数正则表达式基于\w
定义\b
。好吧,except for Java [Point 9] ,其中在默认模式下,\w
仅为ASCII,\w
部分支持Unicode。 < / p>
在JavaScript中,默认模式为\b
。
在.NET中,[A-Za-z0-9_]
默认情况下会匹配\w
,如果指定了ECMAScript option,它将与JavaScript具有相同的行为。在list of characters in Pc category中,您只需要知道不包含空格(ASCII 32)。
根据上面的定义,回答问题变得容易:
[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\P{Lm}\p{Nd}\p{Pc}]
在"hi hello# world#"
中,hello#
为空格(U+0020, in Zs category)后,这不是单词字符,而#
不是单词字符本身({{3} })。因此,#
可以在这里匹配。在这种情况下使用分支\B
。
在(?<!\w)(?!\w)
中,world#
结束字符串后。由于#
不是单词字符,并且我们无法找到前面的任何单词字符(没有任何内容),#
可以匹配\B
之后的空字符串。在这种情况下也使用分支#
。
艾伦·摩尔在in Unicode, it is in Po category中给出了相当不错的总结:
我认为要记住的关键点是正则表达式无法读取。也就是说,他们不会用文字来处理,只能用字符来处理。当我们说
(?<!\w)(?!\w)
匹配单词的开头或结尾时,我们并不是说它标识一个单词然后找出它的终点,就像人类一样。它只能看到之前的当前位置和之后的当前位置。因此,\b
仅表示当前位置可能是字边界。你要确保两边的角色应该是什么样的。
答案 1 :(得分: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
答案 2 :(得分:1)
#
和空格都是非单词字符,因此它们之间的不可见边界不是单词边界。因此\b
与之匹配,\B
将与之匹配。