TLDR: use em theString = theString.replace("\\", "\\\\");vez disso.
Problema
replaceAll(target, replacement)usa sintaxe de expressão regular (regex) para targete parcialmente para replacement.
O problema é que \é um caractere especial em regex (pode ser usado como \dpara representar dígito) e em literal de String (pode ser usado como "\n"para representar separador de linha ou \"para escapar do símbolo de aspas duplas que normalmente representaria o fim da literal de string).
Em ambos os casos, para criar um \símbolo, podemos escapá- lo (torná-lo literal em vez de um caractere especial) colocando mais \antes dele (como escapamos "em literais de strings via \").
Portanto, a targetexpressão regular que representa o \símbolo precisará ser mantida \\, e a string literal que representa esse texto precisará se parecer "\\\\".
Então, escapamos \duas vezes:
- uma vez na regex
\\
- uma vez no literal String
"\\\\"(cada um \é representado como "\\").
No caso de replacement \também é especial lá. Ele nos permite escapar de outro caractere especial $que, por meio de $xnotação, nos permite usar parte dos dados correspondidos por regex e mantidos capturando o grupo indexado x, como, por exemplo , "012".replaceAll("(\\d)", "$1$1")irá corresponder a cada dígito, colocá-lo no grupo de captura 1 e $1$1substituí-lo por suas duas cópias (duplicará) resultando em "001122".
Então, novamente, para deixar replacementrepresentar \literal, precisamos escapar dela com mais, o \que significa que:
- a substituição deve conter dois caracteres de barra invertida
\\
- e String literal que representa
\\parece"\\\\"
MAS, como queremos replacementmanter duas barras invertidas, precisaremos "\\\\\\\\"(cada uma \representada por uma "\\\\").
Então, a versão com replaceAllpode parecer
replaceAll("\\\\", "\\\\\\\\");
Maneira mais fácil
Para tornar a vida mais fácil Java fornece ferramentas para escapar automaticamente texto targete replacementpartes. Portanto, agora podemos focar apenas em strings e esquecer a sintaxe regex:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
que no nosso caso pode parecer
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
Melhor ainda
Se realmente não precisamos de suporte à sintaxe regex, não vamos envolver replaceAllnada. Em vez disso, vamos usar replace. Ambos os métodos substituirão todos os target s, mas replacenão envolvem sintaxe regex. Então você poderia simplesmente escrever
theString = theString.replace("\\", "\\\\");