Frage

Ich versuche, die String \something\ in die String \\something\\ mit replaceAll zu konvertieren, aber ich halte alle Arten von Störungen zu erhalten. Ich dachte, das war die Lösung:

theString.replaceAll("\\", "\\\\");

Aber das gibt die folgende Ausnahme:

java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
War es hilfreich?

Lösung

Die String#replaceAll() interpretiert das Argument als regulärer Ausdruck . Die \ ist ein Escape-Zeichen in beide String und regex. Sie müssen doppelt entkommen es für regex:

string.replaceAll("\\\\", "\\\\\\\\");

Aber Sie brauchen nicht unbedingt regex für dieses, nur weil Sie einen genauen Charakter-by-Charakter Ersatz und Sie keine Muster hier brauchen. So String#replace() sollte genügen:

string.replace("\\", "\\\\");

Aktualisieren : wie pro die Kommentare, Sie scheinen zu wollen, die Zeichenfolge in JavaScript-Kontext verwenden. Sie würden vielleicht besser verwenden StringEscapeUtils#escapeEcmaScript() stattdessen mehr Zeichen zu decken.

Andere Tipps

Mit dieser Art von Schwierigkeiten zu vermeiden, können Sie verwenden replace (das dauert eine einfache Zeichenfolge) statt replaceAll (die einen regulären Ausdruck kommt). Sie werden immer noch Schrägstriche entkommen müssen, aber nicht in den wilden Wege mit regulären Ausdrücken erforderlich.

TLDR. Verwendung theString = theString.replace("\\", "\\\\"); statt


Problem

replaceAll(target, replacement) verwendet reguläre Ausdruck (regex) Syntax für target und teilweise für replacement.

Das Problem ist, dass \ ist Sonderzeichen in regex (kann es wie \d verwendet werden, um repräsentiert Ziffer) und in Stringliteral (es kann wie "\n" verwendet werden doppelte Anführungszeichen Symbol darzustellen Linie Separator oder \" zu entkommen, die normalerweise Ende darstellen würde von Stringliteral).

In diesen beiden Fällen \ Symbol zu schaffen, wir können entkommen es (es wörtliche statt Sonderzeichen) durch zusätzliche \ platzieren, bevor es (wie wir " in Stringliterale über \" entkommen).

So zu target regex \ Symbol darstellt, muß \\ halten, und Stringliteral repräsentiert solcher Text muß wie "\\\\" aussehen.

So entkam wir \ zweimal:

  • einmal in regex \\
  • einmal in Stringliteral "\\\\" (jeweils \ als "\\" dargestellt).

Bei replacement \ ist auch dort etwas Besonderes. Es erlaubt uns, andere Sonderzeichen $ zu entkommen, die über $x Notation, uns Teil der Daten durch regex und gehalten durch die Erfassung Gruppe indiziert als x, wie "012".replaceAll("(\\d)", "$1$1") abgestimmt zu verwenden, ermöglicht wird jede Ziffer entspricht, legen Sie es die Gruppe 1 und $1$1 bei der Erfassung ersetzen es mit seinen zwei Kopien (es wird es duplizieren), was zu "001122".

Also noch einmal, lassen replacement repräsentieren \ wörtlichen müssen wir es mit zusätzlichen \ entkommen, was bedeutet, dass:

  • Ersatz müssen zwei Backslash-Zeichen halten \\
  • und Zeichenkette, die \\ repräsentiert sieht aus wie "\\\\"

Da wir aber replacement wollen halten zwei Schrägstriche werden wir "\\\\\\\\" müssen (jeweils \ durch ein "\\\\" dargestellt).

So Version mit replaceAll kann wie folgt aussehen

replaceAll("\\\\", "\\\\\\\\");

Einfacher Weg

Um das Leben heraus einfacher Java bietet Tools automatisch Text zu entkommen in target und replacement Teile. So, jetzt können wir nur auf Saiten konzentrieren, und vergessen Sie regex Syntax:

replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))

, die in unserem Fall kann wie

aussehen
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))

Noch besser

Wenn wir nicht wirklich regex Syntax Unterstützung brauchen nicht replaceAll überhaupt einbeziehen lässt. Stattdessen lässt Gebrauch replace. Beide Methoden ersetzen alle targets, aber replace beinhaltet nicht regex Syntax. So können Sie einfach schreiben

theString = theString.replace("\\", "\\\\");

Sie müssen den (entkommen) Backslash im ersten Argumente zu entkommen, wie es ein regulärer Ausdruck ist. Replacement (2. Argument - siehe Matcher # replaceAll (String) ) hat auch eine besondere Bedeutung von Backslash es ist, so dass Sie die ersetzen, müssen werden:

theString.replaceAll("\\\\", "\\\\\\\\");

Ja ... durch die Zeit, die Regex Compiler sieht das Muster, das Sie ihm gegeben haben, sieht es nur einen einzigen Schrägstrich (da Java Lexer die doppelte backwhack zu einem einzigen gedreht hat). Sie müssen "\\\\" mit "\\\\" ersetzen, es glauben oder nicht! Java braucht wirklich eine gute raw String-Syntax.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top