Java中的replace()和replaceAll()函数

7
以下代码使用Java中的String类的replace()方法。
String a = "abc/xyz";
System.out.println(a.replace("/", "\\"));

在给定的字符串a中,/被替换为\

如果我们使用以下方式的replaceAll()方法,则会出现相同的问题。

System.out.println(a.replaceAll("/", "\\"));

代码会抛出异常java.lang.StringIndexOutOfBoundsException。由于replaceAll()使用的是正则表达式,而replace()方法不是,因此需要添加两个额外的反斜杠\,如下所示。

System.out.println(a.replaceAll("/", "\\\\"));

唯一的问题是,当只使用两个斜杠(如a.replaceAll("/", "\\"))时,为什么会抛出java.lang.StringIndexOutOfBoundsException

另一方面,split()方法最初会发出一个警告Invalid regular expression: Unexpected internal error(我正在使用NetBeans 6.9.1)。
String b="abc\\xyz";
System.out.println(b.split("\\")[0]+b.split("\\")[1]); //Issues a warning as specified.

尝试运行此代码会引发异常java.util.regex.PatternSyntaxException
由于使用了类似replaceAll()的正则表达式,因此需要四个反斜杠。
System.out.println(b.split("\\\\")[0]+b.split("\\\\")[1]);

为什么在上述代码中,a.replaceAll("/", "\\\\");没有提示警告或运行时异常,即使它具有无效的模式?


你为什么要这样做?如果这是为了文件名,请不要改动,它会按原样工作。 - user207421
2个回答

10

根据Javadoc String.replaceAll

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

System.out.println(a.replaceAll("/", Matcher.quoteReplacement("\\")));

3
为什么像这样只使用两个斜杠的方法 a.replaceAll("/", "\") 会抛出 java.lang.StringIndexOutOfBoundsException 异常?
正如您所知,\ 是正则表达式中的元字符。当您在正则表达式中使用 \ 时,它总是后跟另一个字符,例如 \d 或 \s。
您的 java.lang.StringIndexOutOfBoundsException 异常是在尝试评估模式字符串 ITSELF 即 \\ 时发生的,并且在这种情况下找不到必须的后续字符。这不是在参数字符串 a -> abc/xyz 上发生的,因为它尝试执行以下操作:
if (nextChar == '\\') {  //<-- \\ is read here
    cursor++;

    //<--Its attempting to read next character and fails
    nextChar = replacement.charAt(cursor); 
    result.append(nextChar);
    cursor++;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接