Odpowiedzi:
Od wersji Java 1.5 tak :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
, wróci MicE
. Would't można oczekiwać, że do powrotu MICE
, ponieważ nie stosuje się toUpperCase()
na ic
. W moim przykładzie quote()
jest również stosowany na .*
wstawce replaceAll()
. Musisz zrobić coś innego, być .replaceAll("*","\\E.*\\Q")
może zadziałałoby, ale to sprzeczne z intuicją.
*.wav
się w wzorzec wyrażenia regularnego \*\.wav
, a replaceAll zmieniłby go \.*\.wav
, co oznaczałoby, że dopasuj pliki, których nazwa składa się z dowolnej liczby kropek, po których następuje .wav
. Najprawdopodobniej byś tego potrzebował, replaceAll("\\*", ".*")
gdyby poszli z bardziej delikatną implementacją, która polega na rozpoznawaniu wszystkich możliwych aktywnych charcheterów wyrażeń regularnych i unikaniu ich indywidualnie ... czy to byłoby o wiele łatwiejsze?
Różnica pomiędzy Pattern.quote
i Matcher.quoteReplacement
nie była dla mnie jasna, zanim zobaczyłem następujący przykład
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
zastępuje znaki specjalne w ciągach wyszukiwania wyrażeń regularnych, takich jak. | + () Itp., I Matcher.quoteReplacement
zastępuje znaki specjalne w ciągach zastępujących, takich jak \ 1, dla odwołań wstecznych.
quoteReplacement
dba tylko o dwa symbole $
i \
które mogą być na przykład użyte w ciągach zastępczych jako odniesienia wsteczne $1
lub \1
. Dlatego nie można go używać do ucieczki / cytowania wyrażenia regularnego.
$Group$
z T$UYO$HI
. $
Symbol jest wyjątkowy zarówno w strukturze oraz w wymianie:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Myślę, że to, czego szukasz \Q$5\E
. Zobacz także Pattern.quote(s)
wprowadzone w Java5.
Aby uzyskać szczegółowe informacje, zobacz Wzór javadoc.
Po pierwsze, jeśli
nie umieści 1 na końcu. Spojrzy na wyrażenie regularne wyszukiwania dla pierwszej pasującej grupy i podrzędne TO. To właśnie oznacza 1, 2 lub 3 USD w tekście zastępczym: pasujące grupy ze wzorca wyszukiwania.
Często podłączam długie ciągi tekstu do plików .properties, a następnie generuję z nich tematy i treści wiadomości e-mail. Rzeczywiście wydaje się, że jest to domyślny sposób wykonywania i18n w Spring Framework. Umieszczam tagi XML, jako symbole zastępcze, w ciągach i używam replaceAll (), aby zamienić tagi XML na wartości w czasie wykonywania.
Natknąłem się na problem polegający na tym, że użytkownik wprowadził liczbę dolarów i centów ze znakiem dolara. Zadławiono replaceAll (), a w stracktrace pojawiają się:
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)
W tym przypadku użytkownik wpisał gdzieś „3 $” i replaceAll () zaczął szukać wyrażenia regularnego wyszukiwania dla trzeciej pasującej grupy, nie znalazł jednej i rzygnął.
Dany:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
zastępując
msg = msg.replaceAll("<userInput \\/>", userInput);
z
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
Rozwiązać problem. Użytkownik może bez problemu wprowadzać dowolne znaki, w tym znaki dolara. Zachowywał się dokładnie tak, jak można się spodziewać.
Aby zabezpieczyć wzór, możesz zastąpić wszystkie symbole „\\\\”, z wyjątkiem cyfr i liter. A potem możesz umieścić w tym chronionym wzorze swoje specjalne symbole, aby ten wzór działał nie jak głupi cytowany tekst, ale naprawdę jak wzór, ale twój własny. Bez specjalnych symboli użytkownika.
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”) działa dobrze.
Pattern.quote () działa dobrze. Zawiera zdanie ze znakami „ \ Q ” i „ \ E ”, a jeśli nie ma „\ Q” i „\ E”. Jeśli jednak potrzebujesz wykonać prawdziwe wyrażenie specjalne (lub niestandardowe), możesz użyć tego kodu:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Ta metoda zwraca: Niektóre / \ s / wText * / \, **
Kod na przykład i testy:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Symbol ^ (Negacja) służy do dopasowania czegoś, co nie znajduje się w grupie znaków.
To jest link do wyrażeń regularnych
Oto informacje o negacji:
\Q
i\E
. Może to prowadzić do nieoczekiwanych rezultatów, na przykładPattern.quote("*.wav").replaceAll("*",".*")
skutkować\Q.*.wav\E
i nie.*\.wav
, jak można się spodziewać.