【问题标题】:String's replaceAll() method and escape charactersString 的 replaceAll() 方法和转义字符
【发布时间】:2012-06-07 14:33:20
【问题描述】:

线

System.out.println("\\");

打印一个反斜杠 (\)。和

System.out.println("\\\\");

打印双反斜杠 (\\)。明白了!

但是为什么在下面的代码中:

class ReplaceTest
{
    public static void main(String[] args)
    {
        String s = "hello.world";
        s = s.replaceAll("\\.", "\\\\");
        System.out.println(s);
    }
}

是输出:

hello\world

而不是

hello\\world

毕竟,replaceAll() 方法是将点 (\\.) 替换为 (\\\\)。

有人可以解释一下吗?

【问题讨论】:

    标签: java regex string


    【解决方案1】:

    使用正则表达式替换字符时,您可以使用反向引用,例如 \1 来替换匹配项中的分组。

    然而,这意味着反斜杠是一个特殊字符,所以如果你真的想使用反斜杠,它需要被转义。

    这意味着在 Java 字符串中使用它时实际上需要对其进行两次转义。 (首先是字符串解析器,然后是正则表达式解析器。)

    【讨论】:

    • 所以基本上你所说的是字符串解析器将首先将“\\\\”解析为“\\”,正则表达式解析器将进一步解析为“\”。是这样吗??
    • 是的,我有点困惑,因为在问题的示例中,为什么字符串解析器不能将\\. 解析为\.,然后正则表达式将解析为.
    • @ametren 是正确的。在替换的第一部分,它真的是\。因为他正在逃避点,因为那也有特殊的含义,所以变成了'。然后被第二个参数中的字符串替换。
    • 没关系,刚刚意识到我一开始就完全误读了这个问题。
    【解决方案2】:

    replaceAll 的 javadoc 说:

    请注意,替换中的反斜杠 (\) 和美元符号 ($) 字符串可能会导致结果与之前的结果不同 视为文字替换字符串;请参阅 Matcher.replaceAll。 使用 Matcher.quoteReplacement(java.lang.String) 抑制特殊 如果需要,这些字符的含义。

    【讨论】:

    • +1 用于提及 Matcher.quoteReplacement !编辑:删除代码(我不打算用 mini-markdown 缩进它)
    • Pattern.quoteMatcher.quoteReplacement 之间有一个非常重要的区别。如果要忽略搜索字符串中的元字符,则需要使用前者(Pattern.quote)。要在替换字符串中忽略它们(语法略有不同),您需要使用后者 (Matcher.quoteReplacement)。它们彼此不兼容,所以使用正确的!
    【解决方案3】:

    反斜杠是 Java 字符串中的转义字符。例如反斜杠在 Java 中具有预定义的含义。您必须使用“\ \”来定义单个反斜杠。如果你想定义“\w”,那么你必须在你的正则表达式中使用“\\w”。如果你想使用反斜杠作为文字,你必须输入 \ \ \ \ 因为 \ 也是正则表达式中的转义字符。

    【讨论】:

      【解决方案4】:

      这是我评论的格式化附录

      s = s.replaceAll("\\.", Matcher.quoteReplacement("\\"));  
      

      更具可读性和意义
      s = s.replaceAll("\\.", "\\\\\\");
      

      【讨论】:

        【解决方案5】:

        如果您不需要正则表达式进行替换而只需要替换确切的字符串,请在替换前转义正则表达式控制字符

        String trickyString = "$Ha!I'm tricky|.|";
        String safeToUseInReplaceAllString = Pattern.quote(trickyString);
        

        【讨论】:

          【解决方案6】:

          我相信在这种特殊情况下,使用替换而不是全部替换会更容易。 Gonzo 牧师在谈到逃离角色时有正确的答案。

          使用全部替换:

          s = s.replaceAll("\\.", "\\\\\\\\");
          

          使用替换:

          s = s.replaceAll(".", "\\");
          

          replace 只需要一个字符串来匹配,而不是正则表达式。

          【讨论】:

          • 你提到了 replace() 但你使用了 replaceAll() 两次,你应该编辑你的答案吗?
          【解决方案7】:

          我不喜欢这种正则表达式的实现。我们应该能够使用单个 '\' 来转义字符,而不是 '\'。但无论如何,如果你想获得 THIS.Out_Of_That 你可以这样做:

          String prefix = role.replaceFirst("(\\.).*", "");
          

          所以你得到前缀 = THIS;

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-08
            • 1970-01-01
            • 2012-11-20
            • 1970-01-01
            • 2018-03-09
            • 2015-04-28
            相关资源
            最近更新 更多