2009-11-09 193 views
90

我想給String\something\轉換成使用replaceAllString\\something\\,但我不斷收到各種錯誤。我認爲這是解決方案:String.replaceAll單反斜線與雙反斜槓

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

但這給出了以下異常:

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

回答

162

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

6

你需要逃脫(逃脫)反斜槓的第一個參數,因爲它是一個正則表達式。更換(第二個參數 - 見Matcher#replaceAll(String))也有它的反斜槓的特殊意義,所以你必須替換那些:

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

是...的時候正則表達式編譯器看到你給的格局它看起來只有一個反斜槓(因爲Java的詞法分析器已經把雙反擊變成了單一反斜線)。你需要用"\\\\"代替"\\\\",不管你信不信! Java確實需要一個很好的原始字符串語法。

12

爲了避免這種麻煩,您可以使用replace(其採用純字符串)而不是replaceAll(採用正則表達式)。您仍然需要轉義反斜槓,但不能用正則表達式所需的野性方式。

4

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("\\", "\\\\")