在Java中,带引号的正则表达式不匹配任何内容

4

我可以拥有以下示例字符串之一:

Apple $Banana Kiwi

Apple $Banana, Kiwi

Apple $Banana. Kiwi

我需要查找字面上的"$Banana"

在Java 6中,我使用了以下代码:

String quotedStringToFind=Pattern.quote(stringTofind);

我还需要找到完整的单词,因此我尝试了以下方法:
Pattern.compile("\\b"+quotedStringToFind+"\\b");

没有匹配的内容。正则表达式语法是正确的。我不明白为什么它不起作用。


你需要知道输入中是否包含“$Banana”,还是想要提取中间的单词? - Bohemian
@Bohemian,我假设 OP 知道单词是$Banana,因为变量的名称为stringTofind - Sam
2个回答

2
一些问题:
  • $ 是一个保留字符,表示字符串的结束。您需要首先转义任何保留字符 (\^$.|?*+()[{) 或使用 Pattern.LITERAL 编译表达式,就像 @Reiumeus 的答案中一样。
  • Apple $Banana 中空格和 $ 之间没有单词边界,因为它们都是非单词字符。假设您想要在 stringTofind 前面或后面有一个空格,您可以使用这样的表达式:(?<=\\s|^)\\$Banana(?=\\s|$)(注意,这将无法与 Pattern.LITERAL 一起使用,因为它不会计算前后环视)。

-2

单词边界的定义

它在被称为“单词边界”的位置上匹配。这种匹配长度为零。

有三个不同的位置可以作为单词边界:

  • 如果第一个字符是单词字符,则字符串中第一个字符之前。
  • 如果最后一个字符是单词字符,则字符串中最后一个字符之后。
  • 在字符串中两个字符之间,其中一个是单词字符,另一个不是单词字符。

给定

Apple $Banana Kiwi

第一种情况失败了,因为$不是单词字符。因此,在字符串的第一个字符之前不能有任何匹配。

根据你在其他地方的评论,你不想匹配像"$Bananayellow"这样的字符串,因此我们可以假设你想要字面意义上的"$Banana",后面跟着其他不是单词字符的东西。

正如Tim在评论中建议的那样,您可以使用正则表达式(?<!\S)\$Banana\b。该表达式将检查$Banana是否不是由非空白字符前导,并且它后面跟着一个单词边界。

例如,

List<String> testStrings = List.of("Apple $Banana Kiwi",
                                   "Apple $Banana, Kiwi",
                                   "Apple $Banana. Kiwi",
                                   "Apple $Bananayellow. Kiwi");

// need to escape the special `$` character
Pattern pattern = Pattern.compile("(?<!\\S)\\$Banana\\b");

for (String testString : testStrings) {
    Matcher matcher = pattern.matcher(testString);
    if (!matcher.find()) {
        System.out.println("failed to find pattern in string " + testString);
    }
}

这将只打印最后一个包含"$Bananayellow"的字符串,因为它不匹配所使用的Pattern


1
@Sotirios 正则表达式课程继续:(?<!\S) 不仅断言前面有空格,还包括字符串的开头。理想情况下,当 $Banana 是第一个时,您希望模式也能匹配它。 - Tim Biegeleisen

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