TLDR: Verwenden Sie theString = theString.replace("\\", "\\\\");
stattdessen.
Problem
replaceAll(target, replacement)
Verwendet die reguläre Ausdruckssyntax (Regex) für target
und teilweise für replacement
.
Das Problem ist, dass \
es sich um ein Sonderzeichen in Regex (es kann verwendet werden \d
, um eine Ziffer darzustellen) und in einem Zeichenfolgenliteral (es kann verwendet werden "\n"
, um ein Zeilentrennzeichen darzustellen oder \"
um ein doppeltes Anführungszeichen zu umgehen, das normalerweise das Ende des Zeichenfolgenliteral darstellt).
In diesen beiden Fällen erstellen \
Symbol können wir entkommen sie (es anstelle von spezieller Zeichenliteral) durch zusätzliche Platzierung , \
bevor es (wie wir entkommen "
in Stringliterale über \"
).
So target
regex darstellt \
Symbol zu halten brauchen \\
, und Stringliteral solchen Text darstellen wird aussehen müssen "\\\\"
.
Also sind wir \
zweimal geflohen :
- einmal in Regex
\\
- einmal im String-Literal
"\\\\"
(jedes \
wird als dargestellt "\\"
).
Im Falle von replacement
\
ist dort auch etwas Besonderes. Es ermöglicht uns, anderen Sonderzeichen zu entkommen , die es uns $
über die $x
Notation ermöglichen, einen Teil der Daten zu verwenden, die mit Regex übereinstimmen und von einer erfassten Gruppe erfasst werden x
, die wie "012".replaceAll("(\\d)", "$1$1")
jede Ziffer indiziert ist , sie in die Erfassungsgruppe 1 einordnet und durch $1$1
ihre zwei Kopien ersetzt (es wird es duplizieren) was zu "001122"
.
Also noch einmal, lassen replacement
repräsentieren \
wörtliche wir es mit zusätzlichen entweichen müssen , \
was bedeutet , dass:
- Das Ersetzen muss zwei Backslash-Zeichen enthalten
\\
- und String-Literal, das
\\
aussieht wie"\\\\"
ABER da wir zwei Backslashes replacement
halten wollen , werden wir brauchen (jeder durch einen dargestellt )."\\\\\\\\"
\
"\\\\"
So kann die Version mit replaceAll
aussehen
replaceAll("\\\\", "\\\\\\\\");
Einfacherer Weg
Um das Leben einfacher zu machen, bietet Java Tools, mit denen Text automatisch in Teile target
und replacement
Teile verschoben werden kann. Jetzt können wir uns nur auf Zeichenfolgen konzentrieren und die Regex-Syntax vergessen:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
was in unserem Fall so aussehen kann
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
Noch besser
Wenn wir die Unterstützung der Regex-Syntax nicht wirklich brauchen, können wir sie überhaupt nicht einbeziehen replaceAll
. Verwenden wir stattdessen replace
. Beide Methoden ersetzen alle target
s, beinhalten jedoch replace
keine Regex-Syntax. Sie könnten also einfach schreiben
theString = theString.replace("\\", "\\\\");