Java和JavaScript中的正则表达式\b

3
有没有使用Java和JS中的正则表达式\b的区别?
我进行了以下测试:
在JavaScript中:
console.log(/\w+\b/.test("test中文"));//true  

在Java中:

String regEx = "\\w+\\b";
text = "test中文";
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(text);
while(matcher.find()) {
    System.out.println("matched");//never executed
}

为什么上述两个例子的结果不同?

1
JavaScript正则表达式不理解Unicode。 - georg
2个回答

3
那是因为默认情况下Java支持\b的Unicode,但不支持\w的Unicode, 而JavaScript两者都不支持。
所以\w只能匹配[a-zA-Z0-9_]字符(在我们的例子中是test),但\b不能接受位置(用|标记)。
test|中文

由于Unicode标准将t都视为字母字符,因此在字母和非字母Unicode标准之间存在区别。

如果要忽略Unicode,可以使用环视机制并将其重写为(?:(?<=\\w)(?!\\w)|(?<!\\w)(?=\\w)),或者在这个例子中简单地使用(?!\\w)代替\\b

如果想让\w也支持Unicode,请使用Pattern.UNICODE_CHARACTER_CLASS标志(也可以写成标志表达式(?U))编译您的模式。


1
请注意,通常情况下您不需要编写(?:(?<=\\w)(?!\\w)|(?<!\\w)(?=\\w))的所有内容,因为在几乎任何情况下,它的某些部分都是多余的。在OP的情况下,\\b的非Unicode版本只需为(?!\\w) - ruakh
此外,在Java中,\b\w的定义不同步。\b默认是_加上Character.isLetterOrDigit()(它是Unicode感知的,但这个实现是不正确的),在UNICODE_CHARACTER_CLASS模式下,将与\w的定义同步。 - nhahtdh

1
Jeva正则表达式寻找一个单词字符序列,即[a-zA-Z_0-9]+,在一个单词边界之前。但中文不适用于\w。如果您仅使用\\b,将找到两个匹配项:字符串的开头和结尾。
正如georg所指出的那样,Javascript没有像Java的Regex引擎一样解释字符。

2
这实际上很奇怪,因为单词边界应该在\w\W之间的边界上。由于test匹配\w+,而中文匹配\W+,所以应该有一个\b - RealSkeptic
Java的正则表达式引擎在早期版本中也存在问题。在这里,“text”匹配“\w+\W+”,但不匹配“\w+\b”,这与基本逻辑相反。(1.8.0_20) - laune

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接