2009-06-03 3 views
14

Ich verwende Matcher.appendReplacement() und es funktionierte großartig, bis mein Ersatz-String ein $ 2 in sich hatte:Matcher.appendReplacement mit Literaltext

Beachten Sie, dass Schrägstriche (\) und Dollar Zeichen ($) in der Ersatzzeichenfolge kann dazu führen, dass die Ergebnisse unterschiedlich sind als wenn es als Literal Ersatz Zeichenfolge behandelt würde. Dollar Zeichen können als Verweise auf erfasste Untersequenzen behandelt werden, wie oben beschrieben , und Backslashes werden Escape-Literalzeichen in der Ersetzungszeichenfolge verwendet.

Gibt es irgendwo eine Convenience-Methode, die alle Backslashes \ und Dollarzeichen $ mit einem Backslash entfernt? Oder muss ich selbst eines schreiben? Es klingt wie es nicht so schwer ist, wäre nur schön, wenn sie gaben Sie ein> :(

edit: da sie Ihnen eine geben, ich muss replace(">:(", ":-)");

+0

Hinweis: Dies ist kein Duplikat von "How to Text für regulären Ausdruck in Java zu entkommen". –

+0

Entschuldigung. Ich sah, dass die # 2 Antwort zeigte, wie man quoteReplacement verwendet und nicht die Mühe machte, das Ganze zu lesen. –

+0

Sieht aus wie ein Duplikat von http://stackoverflow.com/questions/60160/how-to-escape-text-for-regular-expression-in-java zu mir. – daveb

Antwort

18

Verwenden Matcher.quoteReplacement auf der Ersatzzeichenfolge.

Leider „-Nutzung“ in diesem Fall im Widerspruch zu starken Typisierung [Erklärung:... Ein Ziel von Java statischem Typ java.lang.String ist jede unveränderliche Folge von char s Es ist Sie nicht sagen, das Format, dass Rohdaten in Dieses Szenario haben wir Text wahrscheinlich für den Benutzer sinnvoll, Text in einer Mini-Sprache für Ersatz codiert ent und Text kodiert in einer Mini-Sprache für das Muster. Das Java-System hat keine Möglichkeit, diese zu unterscheiden (obwohl Sie mit Annotation-basierten Typ-Checkern Spaß machen können, oft um XSS- oder SQL/Command-Injection-Schwachstellen zu vermeiden). Für die Muster-Minisprache kann man mit Pattern.compile eine Form der Konvertierung erstellen, obwohl das eine bestimmte Verwendung ist und die meisten APIs-Methoden es ignorieren (für die Benutzerfreundlichkeit). Ein Äquivalent ReplacementText.compile könnte geschrieben werden. Außerdem könnten Sie die Minisprachen ignorieren und Bibliotheken als "DSLs" betrachten. Aber all dies nicht hilft, lässig einfache Bedienung]

+0

Hey, alles klar! Wie habe ich das aus dem Javadoc vermisst?!?!?!? !! –

+0

Sehr leicht gemacht. –

+1

"Leider" Benutzerfreundlichkeit "in diesem Fall Konflikte mit starker Typisierung." Wie das? –

3

Ich habe es mit der folgenden zu arbeiten, aber Ich mag Tom Hawtin Lösung besser :-)

private static Pattern escapePattern = Pattern.compile("\\$|\\\\"); 
replacement = escapePattern.matcher(replacement).replaceAll("\\\\$0"); 
matcher.appendReplacement(stringbuffer, replacement); 

Tom Lösung:.

matcher.appendReplacement(stringbuffer, Matcher.quoteReplacement(replacement)); 
11

Hier ist eine andere Option:

matcher.appendReplacement(stringbuffer, ""); 
stringbuffer.append(replacement); 

appendReplacement() übernimmt die Aufgabe des Kopierens über der Text zwischen den Übereinstimmungen, dann StringBuffer#append() fügt Ihren Ersetzungstext sans Verfälschungen hinzu. Dies ist besonders praktisch, wenn Sie den Ersetzungstext dynamisch generieren, wie in Elliott Hughes 'Rewriter.

+1

Dies ist sicherlich die beste Lösung, keine Notwendigkeit, die Ersatzzeichenfolge zu analysieren und zu entschlüsseln. –

+0

Schön und einfach. Vielen Dank! – vtuhtan