TLDR: usa theString = theString.replace("\\", "\\\\");invece.
Problema
replaceAll(target, replacement)usa la sintassi delle espressioni regolari (regex) per targete parzialmente per replacement.
Il problema è che \è un carattere speciale in regex (può essere usato come \dper rappresentare una cifra) e in String literal (può essere usato come "\n"per rappresentare il separatore di riga o \"per sfuggire al simbolo di virgolette doppie che normalmente rappresenterebbe la fine della stringa letterale).
In entrambi questi casi, per creare un \simbolo possiamo sfuggirgli (renderlo letterale invece di un carattere speciale) inserendo ulteriori \prima di esso (come se "usassimo l' escape in stringhe letterali tramite \").
Quindi per targetregex che rappresenta il \simbolo sarà necessario tenere \\e la stringa letterale che rappresenta tale testo dovrà essere simile "\\\\".
Quindi siamo fuggiti \due volte:
- una volta in regex
\\
- una volta in String literal
"\\\\"(ognuno \è rappresentato come "\\").
In caso di replacement \è anche speciale lì. Ci permette di sfuggire ad altri caratteri speciali $che, tramite $xnotazione, ci permette di usare parte di dati abbinati da regex e trattenuti catturando il gruppo indicizzato come x, come "012".replaceAll("(\\d)", "$1$1")corrisponderà ad ogni cifra, lo $1$1metterà nel gruppo di cattura 1 e lo sostituirà con le sue due copie (lo duplicherà) risultando in "001122".
Quindi, di nuovo, per far replacementrappresentare il \letterale dobbiamo evitarlo con addizionale \che significa che:
- la sostituzione deve contenere due caratteri backslash
\\
- e String letterale che rappresenta
\\assomiglia a"\\\\"
MA poiché vogliamo replacementmantenere due backslash avremo bisogno "\\\\\\\\"(ciascuno \rappresentato da uno "\\\\").
Quindi la versione con replaceAllpuò assomigliare
replaceAll("\\\\", "\\\\\\\\");
Modo più semplice
Per rendere la vita più facile, Java fornisce strumenti per eseguire automaticamente l'escape di testo targete replacementparti. Quindi ora possiamo concentrarci solo sulle stringhe e dimenticare la sintassi delle espressioni regolari:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
che nel nostro caso può assomigliare
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
Anche meglio
Se non abbiamo davvero bisogno del supporto della sintassi regex, non coinvolgiamo replaceAllaffatto. Invece usiamo replace. Entrambi i metodi sostituiranno tutti target i messaggi, ma replacenon implicano la sintassi delle espressioni regolari. Quindi potresti semplicemente scrivere
theString = theString.replace("\\", "\\\\");