Saya mencoba membuat aplikasi yang cocok dengan template pesan dengan pesan yang coba dikirim oleh pengguna. Saya menggunakan regex Java untuk mencocokkan pesan. Template / pesan mungkin berisi karakter khusus.
Bagaimana cara mendapatkan daftar lengkap karakter khusus yang perlu di-escape agar regex saya berfungsi dan cocok dalam kasus semaksimal mungkin?
Apakah ada solusi universal untuk meng-escape semua karakter khusus di regex Java?
\Q
dan\E
] dianggap sebagai lolos" - kecuali yang lain\Q
dan\E
(yang berpotensi dapat terjadi dalam regex asli). Jadi, lebih baik menggunakanPattern.quote
seperti yang disarankan di sini dan tidak menciptakan kembali roda.\.[]{}()<>*+-=!?^$|
]
dan}
) hanya perlu dilepaskan setelah membuka jenis tanda kurung yang sama.[]
kurung beberapa karakter (seperti+
dan-
) terkadang bekerja tanpa melarikan diri.sumber
-
dalam[]
mungkin tidak selalu berfungsi karena digunakan untuk menentukan rentang. Lebih aman untuk menghindarinya. Misalnya pola[-]
dan[-)]
senar yang cocok-
tapi tidak dengan[(-)]
.-=!
tidak perlu di-escape, itu tergantung pada konteksnya. Misalnya sebagai satu huruf mereka bekerja sebagai ekspresi reguler.Untuk melarikan diri, Anda bisa menggunakan ini dari Java 1.5 :
Anda akan mencocokkan kata tersebut dengan tepat
$test
sumber
Menurut halaman dokumentasi String Literals / Metacharacters , mereka adalah:
<([{\^-=$!|]})?*+.>
Juga akan keren jika daftar itu direferensikan di suatu tempat dalam kode, tetapi saya tidak tahu di mana itu bisa ...
sumber
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
s.replaceAll("[\\W]", "\\\\$0")
mana\W
menunjukkan karakter non-kata.Menggabungkan apa yang dikatakan semua orang, saya mengusulkan yang berikut ini, untuk menjaga daftar karakter khusus untuk RegExp dengan jelas tercantum dalam String mereka sendiri, dan untuk menghindari keharusan mencoba mengurai ribuan "\\" secara visual. Ini tampaknya bekerja dengan cukup baik untuk saya:
sumber
Atas saran @ Sorin tentang dokumen Pola Java, sepertinya karakter yang harus dihindari adalah:
sumber
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
)
juga harus di-escape, dan bergantung pada apakah Anda berada di dalam atau di luar kelas karakter, mungkin ada lebih banyak karakter untuk di-escape, dalam hal iniPattern.quote
melakukan pekerjaan yang cukup baik dalam meng-escape string untuk digunakan baik di dalam maupun di luar kelas karakter.The
Pattern.quote(String s)
semacam melakukan apa yang Anda inginkan. Namun, hal itu menyisakan sedikit yang diinginkan; itu tidak benar-benar melarikan diri dari karakter individu, hanya membungkus string dengan\Q...\E
.Tidak ada metode yang melakukan persis seperti yang Anda cari, tetapi kabar baiknya adalah sebenarnya cukup mudah untuk melepaskan semua karakter khusus dalam ekspresi reguler Java:
Mengapa ini berhasil? Nah, dokumentasi untuk
Pattern
secara khusus mengatakan bahwa diperbolehkan untuk keluar dari karakter non-alfabet yang tidak harus di-escape:Misalnya,
;
bukan karakter khusus dalam ekspresi reguler. Namun, jika Anda menghindarinya,Pattern
masih akan diartikan\;
sebagai;
. Berikut beberapa contoh lainnya:>
menjadi\>
yang setara dengan>
[
menjadi\[
yang merupakan bentuk pelarian dari[
8
masih8
.\)
menjadi\\\)
yang merupakan bentuk pelolosan dari\
dan(
digabungkan.Catatan: Kuncinya adalah definisi "non-alfabet", yang dalam dokumentasi sebenarnya berarti karakter "non- kata ", atau karakter di luar kumpulan karakter
[a-zA-Z_0-9]
.sumber
di sisi lain koin, Anda harus menggunakan regex "non-char" yang terlihat seperti ini jika karakter khusus = allChars - number - ABC - spasi dalam konteks aplikasi Anda.
sumber
meskipun jawabannya adalah untuk Java, tetapi kodenya dapat dengan mudah diadaptasi dari ekstensi String Kotlin yang saya buat ini (diadaptasi dari @brcolow yang disediakan):
cetakan
\(\.\*\)
periksa aksinya di sini https://pl.kotl.in/h-3mXZkNE
sumber
Dengan asumsi bahwa Anda memiliki dan mempercayai (untuk menjadi otoritatif) daftar karakter escape yang digunakan Java regex (alangkah baiknya jika karakter ini diekspos di beberapa anggota kelas Pattern), Anda dapat menggunakan metode berikut untuk melarikan diri dari karakter jika memang diperlukan:
sumber