TLDR: utilisez theString = theString.replace("\\", "\\\\");
plutôt.
Problème
replaceAll(target, replacement)
utilise la syntaxe d'expression régulière (regex) pour target
et partiellement pour replacement
.
Le problème est qu'il \
s'agit d'un caractère spécial dans l'expression régulière (il peut être utilisé comme \d
pour représenter un chiffre) et dans une chaîne littérale (il peut être utilisé comme "\n"
pour représenter un séparateur de ligne ou \"
pour échapper un double guillemet qui normalement représenterait la fin de la chaîne littérale).
Dans ces deux cas, pour créer un \
symbole, nous pouvons l' échapper (le rendre littéral au lieu d'un caractère spécial) en le plaçant \
devant lui (comme nous nous échappons "
dans une chaîne littérale via \"
).
Donc, pour target
regex représentant un \
symbole, il faudra tenir \\
, et une chaîne littérale représentant un tel texte devra ressembler à "\\\\"
.
Nous nous sommes donc échappés \
deux fois:
- une fois dans regex
\\
- une fois dans String littéral
"\\\\"
(chacun \
est représenté par "\\"
).
En cas de replacement
\
c'est aussi spécial là-bas. Cela nous permet d'échapper à un autre caractère spécial $
qui, via la $x
notation, nous permet d'utiliser une partie des données appariées par regex et détenues par le groupe de capture indexé comme x
, comme "012".replaceAll("(\\d)", "$1$1")
correspondra chaque chiffre, placez-le dans le groupe de capture 1 et $1$1
le remplacera par ses deux copies (il le dupliquera) résultant en "001122"
.
Encore une fois, pour laisser replacement
représenter \
littéral, nous devons lui échapper avec un supplément, \
ce qui signifie que:
- le remplacement doit contenir deux barres obliques inverses
\\
- et String littéral qui représente
\\
ressemble à"\\\\"
MAIS puisque nous voulons replacement
contenir deux contre-obliques, nous aurons besoin "\\\\\\\\"
(chacun \
représenté par un "\\\\"
).
Donc la version avec replaceAll
peut ressembler à
replaceAll("\\\\", "\\\\\\\\");
Un moyen plus simple
Pour vous faciliter la vie, Java fournit des outils permettant d'échapper automatiquement le texte dans target
et dans des replacement
parties. Alors maintenant, nous pouvons nous concentrer uniquement sur les chaînes et oublier la syntaxe 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. Au lieu de cela, utilisons replace
. Les deux méthodes remplaceront tous les target
s, mais replace
n'impliquent pas de syntaxe regex. Pour que tu puisses simplement écrire
theString = theString.replace("\\", "\\\\");