Antworten:
Seit Java 1.5 ja :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
, wird es zurückkehren MicE
. Sie könnte nicht erwarten , dass es zurück , MICE
weil Sie nicht anwenden toUpperCase()
auf ic
. In meinem Beispiel quote()
wird das .*
Insertet auch von angewendet replaceAll()
. Sie müssen etwas anderes tun, .replaceAll("*","\\E.*\\Q")
würde vielleicht funktionieren, aber das ist nicht intuitiv.
*.wav
in das Regex-Muster verwandeln \*\.wav
, und das replaceAll würde es in verwandeln \.*\.wav
, was bedeutet, dass dies der Fall wäre Übereinstimmungsdateien, deren Name aus einer beliebigen Anzahl von Punkten besteht, gefolgt von .wav
. Sie hätten es höchstwahrscheinlich nötig gehabt, replaceAll("\\*", ".*")
wenn sie sich für die fragilere Implementierung entschieden hätten, die darauf beruht, alle möglichen aktiven Regex-Zeichen zu erkennen und sie einzeln zu umgehen ... wäre das so viel einfacher?
Der Unterschied zwischen Pattern.quote
und Matcher.quoteReplacement
war mir nicht klar, bevor ich das folgende Beispiel sah
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
insbesondere Sonderzeichen in Regex-Suchzeichenfolgen wie. | + () Matcher.quoteReplacement
Usw. und ersetzt Sonderzeichen in Ersatzzeichenfolgen wie \ 1 für Rückreferenzen.
quoteReplacement
nur Sorgen um die beiden Symbole $
und \
welche beispielsweise in Ersatzzeichenfolgen als Rückreferenzierungen verwendet werden $1
oder \1
. Es darf daher nicht verwendet werden, um einem regulären Ausdruck zu entkommen / ihn zu zitieren.
$Group$
mit T$UYO$HI
. Das $
Symbol ist sowohl im Muster als auch im Ersatz besonders:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Es kann zu spät sein, um zu antworten, aber Sie können auch Folgendes verwenden Pattern.LITERAL
, bei dem alle Sonderzeichen beim Formatieren ignoriert werden:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Ich denke, was Sie suchen, ist \Q$5\E
. Siehe Pattern.quote(s)
auch in Java5 eingeführt.
Weitere Informationen finden Sie unter Muster- Javadoc.
Zunächst einmal, wenn
Am Ende wird keine 1 gesetzt. Es wird der Such-Regex für die erste übereinstimmende Gruppe und das Unter-DAS angezeigt. Das bedeutet 1 $, 2 $ oder 3 $ im Ersatztext: Übereinstimmende Gruppen aus dem Suchmuster.
Ich füge häufig lange Textzeichenfolgen in .properties-Dateien ein und generiere dann aus diesen E-Mail-Betreffs und -Körper. In der Tat scheint dies die Standardmethode für i18n in Spring Framework zu sein. Ich füge XML-Tags als Platzhalter in die Zeichenfolgen ein und verwende replaceAll (), um die XML-Tags zur Laufzeit durch die Werte zu ersetzen.
Ich bin auf ein Problem gestoßen, bei dem ein Benutzer eine Dollar-und-Cent-Zahl mit einem Dollarzeichen eingegeben hat. replaceAll () ist daran erstickt, wobei Folgendes in einer Spur angezeigt wird:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
In diesem Fall hatte der Benutzer irgendwo in seiner Eingabe "$ 3" eingegeben und replaceAll () suchte im Suchbegriff nach der dritten übereinstimmenden Gruppe, fand keine und kotzte.
Gegeben:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
ersetzen
msg = msg.replaceAll("<userInput \\/>", userInput);
mit
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
Problem gelöst. Der Benutzer kann ohne Probleme jede Art von Zeichen, einschließlich Dollarzeichen, eingeben. Es hat sich genau so verhalten, wie Sie es erwarten würden.
Um ein geschütztes Muster zu erhalten, können Sie alle Symbole mit Ausnahme von Ziffern und Buchstaben durch "\\\\" ersetzen. Und danach können Sie in dieses geschützte Muster Ihre speziellen Symbole einfügen, damit dieses Muster nicht wie dumm zitierter Text funktioniert, sondern wirklich wie ein Muster, sondern wie Ihr eigenes. Ohne benutzerspezifische Symbole.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote ("blabla") funktioniert gut.
Das Pattern.quote () funktioniert gut. Es schließt den Satz mit den Zeichen " \ Q " und " \ E " ein, und wenn er nicht "\ Q" und "\ E" enthält. Wenn Sie jedoch einen echten Escape-Ausdruck für reguläre Ausdrücke (oder einen benutzerdefinierten Escape-Vorgang) ausführen müssen, können Sie diesen Code verwenden:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Diese Methode gibt Folgendes zurück: Some / \ s / wText * / \, **
Code zum Beispiel und Tests:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
^ Das Symbol (Negation) wird verwendet, um etwas zu finden, das nicht zur Zeichengruppe gehört.
Dies ist der Link zu regulären Ausdrücken
Hier sind die Bildinformationen zur Negation:
\Q
und umschließt\E
. Dies kann zu unerwarteten Ergebnissen führen, die beispielsweisePattern.quote("*.wav").replaceAll("*",".*")
zu\Q.*.wav\E
und nicht zu den erwarteten Ergebnissen führen.*\.wav
.