String的replaceAll()方法和转义字符

Sur*_*ran 22 java regex string

这条线

System.out.println("\\");
Run Code Online (Sandbox Code Playgroud)

打印单个反斜杠(\).和

System.out.println("\\\\");
Run Code Online (Sandbox Code Playgroud)

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

但为什么在以下代码中:

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

是输出:

hello\world
Run Code Online (Sandbox Code Playgroud)

代替

hello\\world
Run Code Online (Sandbox Code Playgroud)

毕竟,该replaceAll()方法正在用(\\.)替换dot (\\\\).

有人可以解释一下吗?

Rev*_*nzo 24

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

但是,这意味着反斜杠是一个特殊字符,因此如果您确实想要使用反斜杠,则需要对其进行转义.

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

  • 所以基本上你所说的是字符串解析器首先将"\\\\"解析为"\\",正则表达式解析器将进一步解析为"\".是吗? (3认同)
  • @ametren说的没错.在替换的第一部分,它真的\.因为他正在逃避点,因为它具有特殊的意义,所以它变得只是'.' 然后由第二个参数中的字符串替换. (2认同)

JB *_*zet 17

replaceAll的javadoc 说:

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

  • 提到Matcher.quoteReplacement的+1!编辑:删除代码(我不想用迷你降价缩进它) (3认同)

Chr*_*lin 7

这是我的评论的格式化附录

s = s.replaceAll("\\.", Matcher.quoteReplacement("\\"));  
Run Code Online (Sandbox Code Playgroud)

比以下内容更具可读性和意义

s = s.replaceAll("\\.", "\\\\\\");
Run Code Online (Sandbox Code Playgroud)


Gor*_*rky 6

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

String trickyString = "$Ha!I'm tricky|.|";
String safeToUseInReplaceAllString = Pattern.quote(trickyString);
Run Code Online (Sandbox Code Playgroud)