将整个单词与前导或尾随特殊符号(如字符串中的美元)匹配

Matching a whole word with leading or trailing special symbols like dollar in a string

我可以使用 Matcher.quoteReplacement. 来替换美元符号 我可以通过添加边界字符来替换单词:

from = "\b" + from + "\b"; 
outString = line.replaceAll(from, to);

但我似乎无法将它们组合起来用美元符号替换单词。

举个例子。我正在尝试将“$temp4”(不是 $temp40)替换为“register1”。

        String line = "add, $temp4, $temp40, 42";
        String to = "register1";
        String from = "$temp4";
        String outString;


        from = Matcher.quoteReplacement(from);
        from = "\b" + from + "\b";  //do whole word replacement

        outString = line.replaceAll(from, to);
        System.out.println(outString);

输出

"add, $temp4, $temp40, 42"

我怎样才能用它替换 $temp4 并且只替换 $temp4?

Matcher.quoteReplacement() 用于替换字符串 (to),而不是正则表达式 (from)。要在正则表达式中包含字符串文字,请使用 Pattern.quote():

from = Pattern.quote(from);

$ 在正则表达式中有特殊含义(表示“输入结束”)。要从目标中的字符中删除任何特殊含义,请将其包装在正则表达式 quote/unquote 表达式 \Q...\E 中。另外,因为 $ 不是“单词”字符,单词边界不会失效,所以使用 look arounds 代替:

line = line.replaceAll("(?<!\S)\Q" + from + "\E(?![^ ,])", to);

通常,Pattern.quote 是转义可能被正则表达式引擎特殊解释的字符的方法。

但是,正则表达式还是不正确,因为line中的$之前没有分词; space 和 $ 都是非单词字符。您需要将单词边界 放在 字符 $ 之后。这里不需要Pattern.quote,因为你自己在逃避。

String from = "\$\btemp4\b";

或更简单地说,因为您知道 $temp4 之间已经存在单词边界:

String from = "\$temp4\b";

from 变量可以从要替换的表达式构造。如果from"$temp4",那你可以转义美元符号,加个字界。

from = "\" + from + "\b";

输出:

add, register1, $temp40, 42

使用明确的单词边界,(?<!\w)(?!\w),而不是上下文相关的 \b

from = "(?<!\w)" + Pattern.quote(from) + "(?!\w)";

参见regex demo

(?<!\w) 是一个负向后视,如果当前位置的左边有一个非单词字符,则匹配失败,(?!\w) 是一个负向后视,如果匹配失败,则匹配失败当前位置的右边有一个非单词字符。 Pattern.quote(from) 是转义 from 变量中任何特殊字符所必需的。

参见Java demo

String line = "add, $temp4, $temp40, 42";
String to = "register1";
String from = "$temp4";
String outString;

from = "(?<!\w)" + Pattern.quote(from) + "(?!\w)";

outString = line.replaceAll(from, to);
System.out.println(outString);
// => add, register1, $temp40, 42