Matcher的appendReplacement方法忽略替换的反斜杠

时间:2014-12-09 12:32:03

标签: java regex

我有一个字符串s和一个正则表达式。我想用替换字符串替换s中正则表达式的每个匹配项。替换字符串可能包含一个或多个反斜杠。要执行替换,我使用Matcher的{​​{3}}方法。

appendReplacement的问题在于它忽略了它在替换字符串中遇到的所有反冲。因此,如果我尝试使用替换字符串"match"替换字符串"one match"中的子字符串"a\\b",则appendReplacement会生成"one ab"而不是"one a\\b" *:

Matcher matcher = Pattern.compile("match").matcher("one match");
StringBuffer sb = new StringBuffer();
matcher.find();
matcher.appendReplacement(sb, "a\\b");
System.out.println(sb); // one ab

我查看了appendReplacement的代码,发现它跳过任何遇到的反斜杠:

if (nextChar == '\\') {
    cursor++
    nextChar = replacement.charAt(cursor);
    ...
}

如何使用包含反斜杠的替换字符串替换每个匹配项?

(*) - 请注意"a\\b"中只有一个反斜杠,而不是两个。反斜杠刚刚被转义。

3 个答案:

答案 0 :(得分:2)

你需要逃脱逃脱

Matcher matcher = Pattern.compile("match").matcher("one match");
StringBuffer sb = new StringBuffer();
matcher.find();
matcher.appendReplacement(sb, "a\\\\b");
System.out.println(sb);

或者使用replace()

String test="one match";
test=test.replace("match", "a\\b");
System.out.println(test);

输出

one a\b

答案 1 :(得分:2)

你需要双重逃避反斜杠,即:。

matcher.appendReplacement(sb, "a\\\\b");

完整代码:

Matcher matcher = Pattern.compile("match").matcher("one match");
sb = new StringBuffer();
matcher.find();
matcher.appendReplacement(sb, "a\\\\b");
System.out.println(sb); //-> one a/b

原因是Java允许您在替换字符串中使用$1$2等反向引用,并且在主正则表达式中强制执行反斜杠的相同转义机制。

答案 2 :(得分:0)

如果应按字面意义对待替换字符串,请使用Matcher.quoteReplacement。它会转义所有\个字符和$个字符。

String replacement= "a\\b" 
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));