Ich versuche das String
\something\
in das String
\\something\\
using umzuwandeln replaceAll
, aber ich bekomme immer wieder alle möglichen Fehler. Ich dachte das wäre die Lösung:
theString.replaceAll("\\", "\\\\");
Dies gibt jedoch die folgende Ausnahme:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
quelle
String#replaceAll()
trotzdem verwenden möchten, können Sie die Ersatzzeichenfolge mit Matcher # quoteReplacement () zitieren :theString.replaceAll("\\", Matcher.quoteReplacement("\\\\"));
Um diese Art von Problemen zu vermeiden, können Sie
replace
anstelle vonreplaceAll
(für die ein regulärer Ausdruck verwendet wird) (die eine einfache Zeichenfolge verwendet) verwenden . Sie müssen immer noch Backslashes vermeiden, jedoch nicht auf die wilde Weise, die für reguläre Ausdrücke erforderlich ist.quelle
TLDR: Verwenden Sie
theString = theString.replace("\\", "\\\\");
stattdessen.Problem
replaceAll(target, replacement)
Verwendet die reguläre Ausdruckssyntax (Regex) fürtarget
und teilweise fürreplacement
.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 :\\
"\\\\"
(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 werdenx
, 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:\\
\\
aussieht wie"\\\\"
ABER da wir zwei Backslashes
replacement
halten wollen , werden wir brauchen (jeder durch einen dargestellt )."\\\\\\\\"
\
"\\\\"
So kann die Version mit
replaceAll
aussehenEinfacherer Weg
Um das Leben einfacher zu machen, bietet Java Tools, mit denen Text automatisch in Teile
target
undreplacement
Teile verschoben werden kann. Jetzt können wir uns nur auf Zeichenfolgen konzentrieren und die Regex-Syntax vergessen:was in unserem Fall so aussehen kann
Noch besser
Wenn wir die Unterstützung der Regex-Syntax nicht wirklich brauchen, können wir sie überhaupt nicht einbeziehen
replaceAll
. Verwenden wir stattdessenreplace
. Beide Methoden ersetzen alletarget
s, beinhalten jedochreplace
keine Regex-Syntax. Sie könnten also einfach schreibenquelle
Sie müssen den (maskierten) Backslash im ersten Argument umgehen, da es sich um einen regulären Ausdruck handelt. Ersetzen (2. Argument - siehe Matcher # replaceAll (String) ) hat auch die besondere Bedeutung von Backslashes, daher müssen Sie diese ersetzen durch:
quelle
Ja ... bis der Regex-Compiler das von Ihnen angegebene Muster sieht, wird nur ein einziger Backslash angezeigt (da Javas Lexer den doppelten Backwhack in einen einzigen verwandelt hat). Sie ersetzen müssen
"\\\\"
mit"\\\\"
, es glauben oder nicht! Java braucht wirklich eine gute Raw-String-Syntax.quelle