java - 为什么\B 有效但不\b

标签 java javascript .net regex

想要匹配以#结尾的,比如

你好# 世界#

我尝试使用边界

\b\w+#\b

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


令人惊讶的是

\b\w+#\B

匹配!

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


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

最佳答案

词边界的定义\b

在单词中定义单词边界是不精确的。让我用look-aheadlook-behind 和简写单词字符类\w 来定义单词边界。 .

单词边界 \b相当于:

(?:(?<!\w)(?=\w)|(?<=\w)(?!\w))

这意味着:

  • 在前面,(至少)有一个字符是单词字符,在后面,我们找不到单词字符(要么字符不是单词字符,或者它是字符串的开头)。

  • 就在后面,(至少)有一个字符是单词字符,就在前面,我们找不到单词字符(要么字符不是单词字符,要么是字符串的末尾)。

(请注意这与将 XOR 扩展为合取和析取有多么相似)

非单词边界 \B相当于:

(?:(?<!\w)(?!\w)|(?<=\w)(?=\w))

这意味着:

  • 前后左右,都找不到字字符。请注意,在此定义下,空字符串被视为非单词边界。

  • 右前右后,两边都是文字。请注意,此分支需要 2 个字符,即不能出现在非空字符串的开头或结尾。

(请注意这与将 XNOR 扩展为合取和析取有多么相似)。

单词字符的定义\w

\b的定义和 \B取决于 \w 的定义1,需要查阅具体文档才能知道到底是什么\w匹配。

1 大多数正则表达式定义 \b基于 \w .嗯,except for Java [Point 9],在默认模式下,\w是 ASCII-only 和 \b部分识别 Unicode。

问题的答案

有了上面的定义,回答这个问题就变得简单了:

"hi hello# world#"

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

world# , 在 # 之后是字符串的结尾。自 #不是单词字符,我们在前面找不到任何单词字符(那里什么都没有),\B可以匹配#之后的空字符串.分公司(?<!\w)(?!\w)也用于这种情况。

附录

Alan Moore 在 the comment 中给出了很好的总结:

I think the key point to remember is that regexes can't read. That is, they don't deal in words, only in characters. When we say \b matches the beginning or end of a word, we don't mean it identifies a word and then seeks out its endpoints, like a human would. All it can see is the character before the current position and the character after the current position. Thus, \b only indicates that the current position could be a word boundary. It's up to you to make sure the characters on either side what they should be.

关于java - 为什么\B 有效但不\b,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16623181/

相关文章:

java - 使用 Windows 时灰屏,但 JFrame 没问题

java - AsyncTask 执行但只是有时执行

java - 将两个类链接在一起 - Java

javascript - 如何给http get方法返回的变量赋值?

c# - .NET 中是否有一种功能,方法可以通过该功能确定哪个类调用了它

c# - 将 .NET 泛型列表转换为其他泛型列表时遇到问题

java - 基于位置的数据抓取算法

javascript - Meteor:在服务器上正确使用 Meteor.wrapAsync

javascript - 如何将对象转换为关联数组?

c# - 单击DataGridHyperlinkColumn后,WPF MVVM获取行对象