【问题标题】:Matcher.replaceAll - Chokes on $,\ in replacement StringMatcher.replaceAll - 替换字符串中的 $,\ 阻塞
【发布时间】:2023-04-01 03:22:01
【问题描述】:

所以我刚刚遇到了一个很好的边缘情况,如果替换字符串中有 $ 或 \,则在 String 上执行 replaceAll 会阻塞。

为什么替换字符串不只是替换与我指定的正则表达式匹配的替换?我在这里对正则表达式有什么不了解的地方?

引用Oracle Java 7 Documentation:

public String replaceAll(字符串替换)

替换输入序列中匹配的每个子序列 具有给定替换字符串的模式。

此方法首先重置此匹配器。然后扫描输入 序列寻找模式的匹配。不是的字符 任何匹配的一部分都直接附加到结果字符串;每个 match 在结果中被替换字符串替换。这 替换字符串可能包含对捕获子序列的引用 在 appendReplacement 方法中。

请注意,替换中的反斜杠 (\) 和美元符号 ($) 字符串可能会导致结果与之前的结果不同 视为文字替换字符串。美元符号可能会被处理 作为对如上所述捕获的子序列的引用,以及 反斜杠用于转义替换中的文字字符 字符串。

【问题讨论】:

  • 因为$和\在正则表达式中被用作特殊字符,你必须在替换字符串中转义它们。
  • 因为替换字符串能够反向引用匹配器模式中的匹配项(使用$),因此您还需要处理` specially because it is used to escape $`字符(使它们成为文字而不是反向引用)。您实际上引用了文档中解释这一点的部分......

标签: java regex


【解决方案1】:

美元符号是一个特殊字符;你必须逃避它:

"\\$"

注意双反斜杠 - 这就是您在 java 中编写单个反斜杠的方式,这意味着 \$ 被传递给 replace 方法。

美元符号表示对捕获组的反向引用:

"$1" // replace with group 1
"$2" // replace with group 2

还有一个特殊的零组:

"$0" // replace with the entire match

【讨论】:

  • 你的答案也包含其他答案,\也是一个特殊字符,需要转义。
  • 这正是我正在寻找的信息。谢谢~
【解决方案2】:

正如问题所说的那样:

在您的输入中引用捕获的组,替换字符串可以包含您匹配的任何内容:

replaceAll("some str(ing)", "another str$1");

将有效地将“一些”替换为“另一个”。 (愚蠢的例子,但让您了解它的含义。)

【讨论】:

  • 这个例子正是我想要的。谢谢!
  • 刚刚注意到你的名字;我同意 ;)
【解决方案3】:

这有点好笑,但你的引文包含了答案(他们说一个好问题有一半的答案。确实;)。

请注意,替换中的反斜杠 (\) 和美元符号 ($) 字符串可能会导致结果与之前的结果不同 视为文字替换字符串。美元符号可能会被处理 作为对如上所述捕获的子序列的引用,以及 反斜杠用于转义替换中的文字字符 字符串。

用一个额外的斜线将它们转义。

【讨论】:

    【解决方案4】:

    因为$ 可用于对匹配字符串(或匹配字符串的组)进行反向引用,而\ 可用于禁用该行为。

    如果要替换为简单的非正则表达式字符串,请使用Matcher.quoteReplacement()

    String regex = ...;
    String input = ...;
    String replacement = ...;
    input.replaceAll(regex, Matcher.quoteReplacement(replacement));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 2015-10-15
      • 2019-12-30
      • 2011-12-17
      • 2020-03-08
      相关资源
      最近更新 更多