1

我无法让带有前导/尾随 $ 的正则表达式在 Java (1.6.20) 中匹配。

从这段代码:

System.out.println( "$40".matches("\\b\\Q$40\\E\\b") );
System.out.println( "$40".matches(".*\\Q$40\\E.*") );
System.out.println( "$40".matches("\\Q$40\\E") );
System.out.println( " ------ " );
System.out.println( "40$".matches("\\b\\Q40$\\E\\b") );
System.out.println( "40$".matches(".*\\Q40$\\E.*") );
System.out.println( "40$".matches("\\Q40$\\E") );
System.out.println( " ------ " );
System.out.println( "4$0".matches("\\b\\Q4$0\\E\\b") );
System.out.println( "40".matches("\\b\\Q40\\E\\b") );

我得到这些结果:

false
true
true
 ------ 
false
true
true
 ------ 
true
true

前两个区块中的主要错误似乎是问题所在。也就是说,前导/尾随 $(美元符号)在 \b(单词边界)标记的上下文中没有被正确拾取。

块中的真实结果表明它不是引用的美元符号本身,因为将 \b 替换为 .* 或一起删除可以获得所需的结果。

最后两个“真”结果表明,问题既不在于内部引用的 $,也不在于带引号的表达式“\Q ... \E”内的单词边界 (\b) 匹配。

这是一个Java错误还是我错过了什么?

4

2 回答 2

3

这是因为\b匹配单词边界。并且紧接在$字符之前或之后的位置不一定算作单词边界。

单词边界是 和 之间的位置\w\W$不是 的一部分\w。在字符串“bla$”的示例中,单词边界是:

" b l a $ "
 ^----------- here

" b l a $ "
       ^----- here

" b l a $ "
         ^--- but not here
于 2010-07-23T16:10:16.760 回答
1

Tomalak 做到了——它是关于词边界匹配的。我已经想通了并删除了这个问题,但威尔保持对他人开放的建议是合理的。

\b事实上,这就是罪魁祸首。

一个结论可能是,除了最基本的(即 ASCII)用途之外,Java 的内置便捷表达式实际上是无用的。例如。\w仅匹配 ASCII 字符,\b基于此等。

FWIW,我的 RegExp 最终成为:

   (?:^|[\p{P}\p{Z}])(\QThe $earch Term\E)(?:[\p{P}\p{Z}]|$)

The $earch Term我要匹配的文本在哪里。

\p{}Unicode 类别。基本上,我对标点符号 ( P) 或分隔符 ( Z) Unicode 字符类别中的任何字符都违背了我的诺言。同样,输入的开始和结束被尊重(使用^and $)并且边界标记被标记为非捕获组((?:...)位),而实际的搜索词被引用\Q并且\E& 放置在匹配组中。

于 2010-08-13T18:58:32.913 回答