Jawaban:
Sejak Java 1.5, ya :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
akan kembali MicE
. Anda would't berharap untuk kembali MICE
karena Anda tidak berlaku toUpperCase()
pada ic
. Dalam contoh saya quote()
diterapkan pada .*
insertet replaceAll()
juga. Anda harus melakukan sesuatu yang lain, mungkin .replaceAll("*","\\E.*\\Q")
akan berhasil, tetapi itu berlawanan dengan intuisi.
*.wav
menjadi pola regex \*\.wav
, dan ganti Semua akan mengubahnya menjadi \.*\.wav
, berarti itu akan mencocokkan file yang namanya terdiri dari jumlah periode acak diikuti oleh .wav
. Anda kemungkinan besar harus melakukannya replaceAll("\\*", ".*")
jika mereka pergi dengan implementasi yang lebih rapuh yang bergantung pada mengenali semua charachters regex aktif yang mungkin dan melarikan diri secara individual ... apakah itu jauh lebih mudah?
Perbedaan antara Pattern.quote
dan Matcher.quoteReplacement
tidak jelas bagi saya sebelum saya melihat contoh berikut
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
mengganti karakter khusus dalam string pencarian regex, seperti. | + () Dll, dan Matcher.quoteReplacement
menggantikan karakter khusus dalam string pengganti, seperti \ 1 untuk referensi-ulang.
quoteReplacement
hanya peduli pada dua simbol $
dan \
yang misalnya dapat digunakan dalam string pengganti sebagai backreferences $1
atau \1
. Karena itu tidak boleh digunakan untuk melarikan diri / mengutip suatu regex.
$Group$
dengan T$UYO$HI
. The $
simbol khusus baik dalam pola dan penggantian:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Mungkin sudah terlambat untuk merespons, tetapi Anda juga dapat menggunakan Pattern.LITERAL
, yang akan mengabaikan semua karakter khusus saat memformat:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Saya pikir apa yang Anda cari \Q$5\E
. Lihat juga Pattern.quote(s)
diperkenalkan di Java5.
Lihat Pola javadoc untuk detailnya.
Pertama, jika
itu tidak akan menempatkan 1 di akhir. Ini akan melihat regex pencarian untuk grup yang cocok pertama dan sub ITULAH. Itu artinya $ 1, $ 2 atau $ 3 berarti dalam teks pengganti: kelompok yang cocok dari pola pencarian.
Saya sering menyambungkan string panjang teks ke file .properties, lalu menghasilkan subjek dan badan email dari mereka. Memang, ini tampaknya menjadi cara standar untuk melakukan i18n di Spring Framework. Saya menempatkan tag XML, sebagai placeholder, ke dalam string dan saya menggunakan replaceAll () untuk mengganti tag XML dengan nilai-nilai saat runtime.
Saya mengalami masalah ketika pengguna memasukkan angka dolar, dengan tanda dolar. replaceAll () tersedak karenanya, dengan yang berikut ini muncul di 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)
Dalam hal ini, pengguna telah memasukkan "$ 3" di suatu tempat di input mereka dan replaceAll () pergi mencari di regex pencarian untuk kelompok yang cocok ketiga, tidak menemukan satu, dan muntah.
Diberikan:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
mengganti
msg = msg.replaceAll("<userInput \\/>", userInput);
dengan
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
memecahkan masalah. Pengguna dapat memasukkan karakter apa pun, termasuk tanda dolar, tanpa masalah. Itu berperilaku persis seperti yang Anda harapkan.
Untuk memiliki pola yang dilindungi, Anda dapat mengganti semua simbol dengan "\\", kecuali angka dan huruf. Dan setelah itu Anda dapat menempatkan dalam pola yang dilindungi itu simbol khusus Anda untuk membuat pola ini bekerja tidak seperti teks yang dikutip bodoh, tetapi benar-benar seperti patten, tetapi Anda sendiri. Tanpa simbol khusus pengguna.
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") berfungsi dengan baik.
Pattern.quote () berfungsi dengan baik. Itu melampirkan kalimat dengan karakter " \ Q " dan " \ E ", dan jika itu lolos "\ Q" dan "\ E". Namun, jika Anda perlu melakukan pelarian ekspresi reguler yang sebenarnya (atau pelolosan khusus), Anda dapat menggunakan kode ini:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Metode ini mengembalikan: Some / \ s / wText * / \, **
Contoh kode dan tes:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Simbol ^ (Negasi) digunakan untuk mencocokkan sesuatu yang tidak ada dalam grup karakter.
Ini tautan ke Ekspresi Reguler
Ini adalah info gambar tentang negasi:
\Q
dan\E
. Ini dapat menyebabkan hasil yang tidak terduga, misalnyaPattern.quote("*.wav").replaceAll("*",".*")
akan menghasilkan\Q.*.wav\E
dan tidak.*\.wav
, seperti yang Anda harapkan.