Java 中的 replace() 和 replaceAll()

Posted

技术标签:

【中文标题】Java 中的 replace() 和 replaceAll()【英文标题】:replace() and replaceAll() in Java 【发布时间】:2012-10-08 02:54:24 【问题描述】:

以下代码使用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("/", "\\\\"); 在前面的例子中没有发出这样的警告或这样的运行时异常,即使它有一个无效的模式?

【问题讨论】:

你为什么要这样做?如果这是一个文件名,请保留它,它将按原样工作。 【参考方案1】:

来自 Javadoc String.replaceAll

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

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

【讨论】:

【参考方案2】:

为什么这种方法在只使用两个斜杠时会这样 a.replaceAll("/", "\") 抛出 java.lang.StringIndexOutOfBoundsException?

如您所知,\ 是正则表达式中的元字符。当您在正则表达式中使用 \ 时,它后面总是跟着另一个字符,例如\d or \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++;

【讨论】:

以上是关于Java 中的 replace() 和 replaceAll()的主要内容,如果未能解决你的问题,请参考以下文章

javascript中的replace函数同时替换多个字符串

在 postgres 中匹配 regexp_replace 中的 2 个条件

linux 中如何用vi编辑器替换相同的字符?

mysql replace into用法详细说明

如何在 regex_replace() 中使用 db 列名 - presto

SQL:使用 REGEXP_REPLACE 删除表的另一列中的部分字符串