TLDR: utilisez theString = theString.replace("\\", "\\\\");plutôt.
Problème
replaceAll(target, replacement)utilise la syntaxe d'expression régulière (regex) pour targetet 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 \dpour 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 targetregex 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 $xnotation, 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$1le remplacera par ses deux copies (il le dupliquera) résultant en "001122".
Encore une fois, pour laisser replacementrepré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 replacementcontenir deux contre-obliques, nous aurons besoin "\\\\\\\\"(chacun \représenté par un "\\\\").
Donc la version avec replaceAllpeut ressembler à
replaceAll("\\\\", "\\\\\\\\");
Un moyen plus simple
Pour vous faciliter la vie, Java fournit des outils permettant d'échapper automatiquement le texte dans targetet dans des replacementparties. 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 replaceAlldu tout. Au lieu de cela, utilisons replace. Les deux méthodes remplaceront tous les target s, mais replacen'impliquent pas de syntaxe regex. Pour que tu puisses simplement écrire
theString = theString.replace("\\", "\\\\");