使用 lambda 回调的 replaceAll 未按预期工作

replaceAll with lambda callback not working as expected

我对我的 Java-Fu 有点生疏,但我 运行 遇到了一个我不太明白的问题。

我有一个字符串 test\"escape\"test\,我正在尝试将其 运行 转换为 test\"escape"test\(这是在字符串转义之前)。

我发现了这个带有函数回调的漂亮 replaceAll 方法,我正在尝试从所有以反斜杠开头并以引号结尾的子字符串中删除 正好一个 反斜杠(如 \"\",但任何其他出现的反斜杠都应保持不变)。

不幸的是我回来了test"escape"test\,位置 5 的反斜杠比预期少了一个。

这是我试过的代码:

Pattern.compile("(\\+\")")
   .matcher("test\\\"escape\\"test\")
   .replaceAll(mr -> mr.group().substring(1));

我在这里错过了什么?

您的代码的问题在于,您在 lambda 中传递的字符串被视为 替换模式 ,其中 \ 是一个特殊字符。您需要使用 Matcher.quoteReplacement(mr.group().substring(1)):

String output = Pattern.compile("(\\+\")")
           .matcher(text)
           .replaceAll(mr -> Matcher.quoteReplacement(mr.group().substring(1)));

参见Java demo

这里不需要使用lambda,可以使用

String text = "test\\\"escape\\"test\ that";
String output = text.replaceAll("\\(\\*\")", "");
System.out.println(output);
// => test\"escape"test\ that

参见Java demo and the regex demo

\(\*") 正则表达式匹配 \,然后将零个或多个反斜杠与 " 一起捕获到第 1 组中,替换为第 1 组值。