【问题标题】:Matcher's appendReplacement method ignores the replacement's backslashesMatcher 的 appendReplacement 方法忽略了替换的反斜杠
【发布时间】:2014-12-09 12:32:03
【问题描述】:

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

appendReplacement 的问题在于它忽略了在替换字符串中遇到的所有反冲。因此,如果我尝试用替换字符串"a\\b" 替换字符串"one match" 中的子字符串"match",那么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" 中有一个反斜杠,而不是两个。反斜杠只是被转义了。

【问题讨论】:

  • "a"+"\"+"b" ????????
  • @vks:如果您要问我的示例替换字符串是否为"a"+"\"+"b",那么是的,除了"\" 是非法Java 字符串,因为您必须转义反斜杠。
  • 我实际上是在问这种替换是否有效:P

标签: java regex


【解决方案1】:

您需要双重转义反斜杠,即:

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】:

    你需要逃脱转义

    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
    

    【讨论】:

    • 仅供参考,原来的答案只有replace 代码,但现在matcher.appendReplacement(sb, "a\\\\b"); 也出现在我的答案之后
    【解决方案3】:

    如果替换字符串应按字面处理,请使用Matcher.quoteReplacement。它会转义所有 \ 字符以及 $ 字符。

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

    【讨论】:

      猜你喜欢
      • 2012-04-14
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 2014-09-09
      • 1970-01-01
      相关资源
      最近更新 更多