String.replaceAll单反斜线与双反斜杠

问题描述:

我想给String\something\转换成使用replaceAllString\\something\\,但我不断收到各种错误。我认为这是解决方案:String.replaceAll单反斜线与双反斜杠

theString.replaceAll("\\", "\\\\"); 

但这给出了以下异常:

java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 

String#replaceAll()将参数解释为regular expression\均为Stringregex中的转义字符。你需要双击逃避它的正则表达式:

string.replaceAll("\\\\", "\\\\\\\\"); 

但你不一定需要的正则表达式这一点,仅仅是因为你想要一个确切的字符一个字符替换,你不要在这里需要的模式。所以String#replace()应该足够了:

string.replace("\\", "\\\\"); 

更新:根据的评论,你似乎想在JavaScript中使用的上下文的字符串。你最好用StringEscapeUtils#escapeEcmaScript()来代替更多的字符。

+0

实际上,它被用在应该转换回源代码的JavaScript AST中。你的解决方案有效谢谢! – 2009-11-09 15:47:23

+0

如果你想使用'String#replaceAll()',你可以用[Matcher#quoteReplacement()](http://docs.oracle.com/javase/7/docs/api/java/ util/regex/Matcher.html#quoteReplacement(java.lang.String)):'theString.replaceAll(“\\”,Matcher.quoteReplacement(“\\\\”));' – 2015-11-12 17:06:40

你需要逃脱(逃脱)反斜杠的第一个参数,因为它是一个正则表达式。更换(第二个参数 - 见Matcher#replaceAll(String))也有它的反斜杠的特殊意义,所以你必须替换那些:

theString.replaceAll("\\\\", "\\\\\\\\"); 

是...的时候正则表达式编译器看到你给的格局它看起来只有一个反斜杠(因为Java的词法分析器已经把双反击变成了单一反斜线)。你需要用"\\\\"代替"\\\\",不管你信不信! Java确实需要一个很好的原始字符串语法。

为了避免这种麻烦,您可以使用replace(其采用纯字符串)而不是replaceAll(采用正则表达式)。您仍然需要转义反斜杠,但不能用正则表达式所需的野性方式。

replaceAll(target, replacement)target使用正则表达式(正则表达式)语法,部分使用replacement

问题是,\是特殊字符在正则表达式(如\d到代表数字)和字符串文字(如\n创建行分隔符或\"代表双引号符号),并创造\符号,我们需要转义在这两个级别之前还有\

所以创建target正则表达式,这将代表\符号,我们需要转义两次:在正则表达式\\

  • 字符串

    • 文字"\\\\"(每个\需要自己额外\之前)。

    replacement\情况下也特别有逃脱一个其他特殊字符是$。通过$x表示法,正则表达式匹配的部分数据可以被访问并且被重新使用替换,就像replaceAll("(\d)", "$1$1")会重复每个数字一样。

    如此反复,在replacement\我们需要的文字代表两个反斜杠:

    • \\
    • 但字符串字面量较\\样子"\\\\"

    但由于我们要把两个\替代我们需要"\\\\\\\\"那里(两个"\\\\")。

    replaceAll("\\\\", "\\\\\\\\"); 
    

    做出来的生活更轻松Java提供的工具来自动跳脱文本targetreplacement部分。所以,现在我们可以只注重字符串,而忘记了正则表达式语法:

    replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement)) 
    

    这在我们的情况下,可以像

    replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\")) 
    

    或者,即使我们不希望使用更简单正则表达式不涉及replaceAll,而是使用replace(这两种方法都将取代所有target,但第二种方法不涉及正则表达式语法)。所以你可以简单地写

    theString = theString.replace("\\", "\\\\")