Risposte:
Da Java 1.5, sì :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
, tornerà MicE
. Si would't aspetta per tornare MICE
perché non hai applica toUpperCase()
su ic
. Nel mio esempio quote()
viene applicato anche .*
sull'inserto replaceAll()
. Devi fare qualcos'altro, forse .replaceAll("*","\\E.*\\Q")
funzionerebbe, ma è controintuitivo.
*.wav
nel modello regex \*\.wav
e il sostituire All avrebbe trasformato in \.*\.wav
, nel senso che avrebbe confronta i file il cui nome è costituito da un numero arbitrario di periodi seguiti da .wav
. Probabilmente avresti dovuto farlo replaceAll("\\*", ".*")
se fossero andati con l'implementazione più fragile che si basa sul riconoscimento di tutti i possibili caratteri regex attivi e sulla loro fuga individuale ... Sarebbe molto più facile?
La differenza tra Pattern.quote
e Matcher.quoteReplacement
non mi era chiara prima di vedere l'esempio seguente
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
sostituisce i caratteri speciali nelle stringhe di ricerca regex, come. | + () Ecc., E Matcher.quoteReplacement
sostituisce i caratteri speciali nelle stringhe di sostituzione, come \ 1 per i riferimenti indietro.
quoteReplacement
si preoccupa solo dei due simboli $
e \
che, ad esempio, possono essere utilizzati nelle stringhe di sostituzione come riferimenti indietro $1
o \1
. Pertanto non deve essere utilizzato per sfuggire / citare un regex.
$Group$
con T$UYO$HI
. Il $
simbolo è speciale sia nel disegno e nella sostituzione:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Potrebbe essere troppo tardi per rispondere, ma puoi anche usare Pattern.LITERAL
, che ignorerebbe tutti i caratteri speciali durante la formattazione:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Penso che quello che cerchi sia \Q$5\E
. Vedi anchePattern.quote(s)
introdotto in Java5.
Vedi Pattern javadoc per i dettagli.
Prima di tutto, se
non metterà un 1 alla fine. Esaminerà la regex di ricerca per il primo gruppo corrispondente e il sottotitolo in. Ecco cosa significano $ 1, $ 2 o $ 3 nel testo sostitutivo: gruppi corrispondenti dal modello di ricerca.
Inserisco spesso lunghe stringhe di testo in file .properties, quindi genera oggetti e corpi di posta elettronica da quelli. In effetti, questo sembra essere il modo predefinito di fare i18n in Spring Framework. Inserisco i tag XML, come segnaposto, nelle stringhe e utilizzo replaceAll () per sostituire i tag XML con i valori in fase di esecuzione.
Ho riscontrato un problema in cui un utente inseriva una cifra in dollari e centesimi, con un segno di dollaro. replaceAll () soffocato su di esso, con il seguente che appare in una stracktrace:
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 questo caso, l'utente ha inserito "$ 3" da qualche parte nel suo input e sostituisce All () è andato alla ricerca nella regex di ricerca per il terzo gruppo corrispondente, non l'ha trovato e ha vomitato.
Dato:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
sostituzione
msg = msg.replaceAll("<userInput \\/>", userInput);
con
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
problema risolto. L'utente può inserire qualsiasi tipo di carattere, incluso il simbolo del dollaro, senza problemi. Si è comportato esattamente come ti aspetteresti.
Per avere un motivo protetto è possibile sostituire tutti i simboli con "\\\\", tranne cifre e lettere. E dopo puoi inserire in quello schema protetto i tuoi simboli speciali per far funzionare questo schema non come stupido testo tra virgolette, ma davvero come uno zoccolo, ma il tuo. Senza simboli speciali dell'utente.
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") funziona bene.
Pattern.quote () funziona bene. Racchiude la frase con i caratteri " \ Q " e " \ E " e se sfugge a "\ Q" e "\ E". Tuttavia, se devi eseguire l'escaping di un'espressione regolare reale (o l'escaping personalizzato), puoi utilizzare questo codice:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Questo metodo restituisce: Some / \ s / wText * / \, **
Codice per esempio e test:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
^ Il simbolo (Negazione) viene usato per abbinare qualcosa che non è nel gruppo di caratteri.
Questo è il link alle espressioni regolari
Ecco le informazioni sull'immagine relative alla negazione:
\Q
e\E
. Ciò può portare a risultati imprevisti, ad esempio,Pattern.quote("*.wav").replaceAll("*",".*")
si tradurrà in\Q.*.wav\E
e non.*\.wav
, come ci si potrebbe aspettare.