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在这种情况下有效!
\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)
意思是:
在前面和后面,我们找不到任何单词字符.请注意,在此定义下,空字符串被视为非字边界.
要么
(注意这与XNOR扩展为连接和分离有多相似).
\w由于定义\b和\B依赖于\w1的定义,您需要查阅特定文档以确切知道\w匹配的内容.
1大多数正则表达式都\b基于\w.好吧,除了Java [Point 9],默认模式下,它\w只是ASCII,并且\b部分支持Unicode.
在JavaScript中,它将[A-Za-z0-9_]处于默认模式.
在.NET中,\w默认情况下会匹配[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\P{Lm}\p{Nd}\p{Pc}],如果指定了ECMAScript选项,它将具有与JavaScript相同的行为.在Pc类别中的字符列表中,您只需要知道不包含空格(ASCII 32).
根据上面的定义,回答问题变得容易:
"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仅表示当前位置可以是单词边界.你要确保两边的角色应该是什么样的.
英镑#符号不被视为"单词边界".
\b\w+#\b不起作用,因为w+#不被认为是一个单词,因此它不匹配world#.
\b\w+6\b在另一方面,因此它会匹配world6.
"单词字符"定义如下:[A-Za-z0-9_].
简单地说:
\b允许您使用正则表达式执行"仅限整个单词"搜索\bword\b."单词字符"是可用于形成单词的字符.所有不是"单词字符"的字符都是"非单词字符".
- http://www.regular-expressions.info/wordboundaries.html