TLDR : utiliser theString = theString.replace("\\", "\\\\");
à la place.
Problema
replaceAll(target, replacement)
utilise la syntaxe des expressions régulières (regex) pour target
et partiellement pour replacement
.
Le problème est que \
est un caractère spécial dans les regex (il peut être utilisé comme suit \d
pour représenter un chiffre) et dans les chaînes de caractères (il peut être utilisé comme suit "\n"
pour représenter le séparateur de ligne ou \"
pour échapper au symbole du guillemet double qui représente normalement la fin de la chaîne de caractères).
Dans ces deux cas, pour créer \
symbole que nous pouvons s'échapper (en le rendant littéral au lieu d'un caractère spécial) en plaçant un \
avant elle (comme nous échappons "
dans les littéraux de chaînes de caractères via \"
).
Ainsi, pour target
regex représentant \
Le symbole devra tenir \\
et la chaîne littérale représentant ce texte devra ressembler à ceci "\\\\"
.
Nous nous sommes donc échappés \
deux fois :
- une fois en regex
\\
- une fois dans la chaîne littérale
"\\\\"
(chaque \
est représenté par "\\"
).
En cas de replacement
\
est également spécial là-bas. Il nous permet d'échapper à d'autres caractères spéciaux $
qui via $x
la notation, nous permet d'utiliser la partie des données correspondant à la regex et détenue par le groupe de capture indexé comme x
comme "012".replaceAll("(\\d)", "$1$1")
correspondra à chaque chiffre, le placera dans le groupe de capture 1 et $1$1
le remplacera par ses deux copies (il le dupliquera), ce qui donnera comme résultat "001122"
.
Donc, encore une fois, pour laisser replacement
représenter \
littéral, nous devons lui échapper avec des \
ce qui signifie que :
- le remplacement doit contenir deux caractères backslash
\\
- et le littéral String qui représente
\\
ressemble à "\\\\"
MAIS puisque nous voulons replacement
pour tenir deux backslashes dont nous aurons besoin "\\\\\\\\"
(chaque \
représenté par un "\\\\"
).
Donc version avec replaceAll
peut ressembler à
replaceAll("\\\\", "\\\\\\\\");
Un moyen plus facile
Pour nous faciliter la vie, Java fournit des outils permettant d'échapper automatiquement du texte dans des fichiers de type target
y replacement
pièces. Nous pouvons donc maintenant nous concentrer uniquement sur les chaînes de caractères, et oublier la syntaxe des regex :
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
qui, dans notre cas, peut ressembler à
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
Encore mieux
Si nous n'avons pas vraiment besoin du support de la syntaxe regex, n'impliquons pas replaceAll
du tout. Utilisons plutôt replace
. Les deux méthodes remplaceront todo target
mais replace
n'implique pas de syntaxe regex. Vous pouvez donc simplement écrire
theString = theString.replace("\\", "\\\\");