Saya lelah selalu berusaha menebak, jika saya harus melarikan diri karakter khusus seperti ' ()[]{}|
' dll ketika menggunakan banyak implementasi regexps.
Ini berbeda dengan, misalnya, Python, sed, grep, awk, Perl, rename, Apache, find, dan sebagainya. Apakah ada aturan yang menentukan kapan saya harus, dan kapan saya tidak boleh, melarikan diri karakter khusus? Apakah itu tergantung pada jenis regexp, seperti PCRE, POSIX atau regexps diperpanjang?
escape()
" untuk mengizinkan penggunaan string acak sebagai bagian regex.Jawaban:
Karakter mana yang Anda harus dan yang tidak boleh Anda lepaskan memang tergantung pada rasa regex yang Anda kerjakan.
Untuk PCRE, dan sebagian besar yang disebut rasa yang kompatibel dengan Perl, lepas dari kelas karakter luar ini:
dan kelas-kelas karakter di dalam ini:
Untuk POSIX extended regexes (ERE), keluar dari kelas karakter luar ini (sama seperti PCRE):
Melarikan diri dari karakter lain adalah kesalahan dengan POSIX ERE.
Di dalam kelas karakter, garis miring terbalik adalah karakter literal dalam ekspresi reguler POSIX. Anda tidak dapat menggunakannya untuk melarikan diri dari apa pun. Anda harus menggunakan "penempatan pintar" jika Anda ingin memasukkan metakarakter kelas karakter sebagai literal. Letakkan ^ di mana saja kecuali di awal,] di awal, dan - di awal atau di akhir kelas karakter untuk mencocokkan ini secara harfiah, misalnya:
Dalam POSIX basic regular expressions (BRE), ini adalah karakter metak yang perlu Anda hilangkan untuk menekan artinya:
Melarikan kurung dan kurung keriting di BRE memberi mereka makna khusus yang dimiliki versi yang tidak luput dalam ERE. Beberapa implementasi (mis. GNU) juga memberikan arti khusus untuk karakter lain ketika melarikan diri, seperti \? dan +. Melarikan karakter selain dari. ^ $ * () {} Biasanya merupakan kesalahan dengan BRE.
Di dalam kelas karakter, BRE mengikuti aturan yang sama dengan ERE.
Jika semua ini membuat kepala Anda berputar, ambil salinan RegexBuddy . Pada tab Buat, klik Sisipkan Token, lalu Literal. RegexBuddy akan menambahkan lolos sesuai kebutuhan.
sumber
/
bukan metacharacter dalam salah satu dari rasa ekspresi reguler yang saya sebutkan, jadi sintaks ekspresi reguler tidak mengharuskan untuk menghindarinya. Ketika ekspresi reguler dikutip sebagai literal dalam bahasa pemrograman, maka aturan pemformatan string atau regex dari bahasa tersebut mungkin mengharuskan/
atau"
atau'
untuk diloloskan, dan bahkan mungkin mengharuskan `\` untuk kabur dua kali.Modern RegEx Flavours (PCRE)
Termasuk C, C ++, Delphi, EditPad, Java, JavaScript, Perl, PHP (preg), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Studio Asli, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML Schema, Xojo, XRegExp.
Kompatibilitas PCRE dapat bervariasi
Di mana saja:
. ^ $ * + - ? ( ) [ ] { } \ |
Legacy RegEx Flavours (BRE / ERE)
Termasuk awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed.
Dukungan PCRE dapat diaktifkan di versi yang lebih baru atau dengan menggunakan ekstensi
ERE / awk / egrep / emacs
Di luar kelas karakter:
. ^ $ * + ? ( ) [ { } \ |
Di dalam kelas karakter:
^ - [ ]
BRE / ed / grep / sed
Di luar kelas karakter:
. ^ $ * [ \
Di dalam kelas karakter:
^ - [ ]
Untuk literal, jangan melarikan diri:
+ ? ( ) { } |
Untuk perilaku regex standar, melarikan diri:
\+ \? \( \) \{ \} \|
Catatan
\xFF
] -
hanya perlu melarikan diri dalam kelas karakter, tetapi saya menyimpannya dalam satu daftar untuk kesederhanaan"(\")(/)(\\.)"
versus/(")(\/)(\.)/
dalam JavaScript)sumber
-
atau]
untuk keluar dari kelas karakter. POSIX (BRE / ERE) tidak memiliki karakter pelarian di dalam kelas karakter. Rasa regex dalam RTL Delphi sebenarnya didasarkan pada PCRE. Python, Ruby, dan XML memiliki rasa sendiri yang lebih dekat dengan PCRE daripada rasa POSIX.Sayangnya sebenarnya tidak ada satu set kode pelarian karena bervariasi berdasarkan bahasa yang Anda gunakan.
Namun, menjaga halaman seperti Halaman Alat Ekspresi Reguler atau Lembar Kalimat Ekspresi Reguler ini dapat membantu Anda dengan cepat menyaring berbagai hal.
sumber
\<
dan\>
merupakan batas kata, yang hanya benar (AFAIK) di perpustakaan peningkatan Boost. Tetapi di tempat lain dikatakan<
dan>
merupakan metakarakter dan harus melarikan diri (ke\<
dan\>
) untuk mencocokkannya secara harfiah, yang tidak benar dalam rasa apa punSayangnya, makna hal-hal seperti (dan \ (ditukar antara ekspresi reguler gaya Emacs dan sebagian besar gaya lainnya. Jadi, jika Anda mencoba melarikan diri ini, Anda mungkin melakukan kebalikan dari apa yang Anda inginkan.
Jadi, Anda benar-benar harus tahu gaya apa yang ingin Anda kutip.
sumber
POSIX mengenali banyak variasi pada ekspresi reguler - ekspresi reguler dasar (BRE) dan ekspresi reguler yang diperluas (ERE). Dan bahkan kemudian, ada kebiasaan karena implementasi historis dari utilitas yang distandarisasi oleh POSIX.
Tidak ada aturan sederhana untuk kapan menggunakan notasi mana, atau bahkan notasi mana yang diberikan perintah.
Periksa buku Ekspresi Reguler Reguler Jeff Friedl .
sumber
Sungguh, tidak ada. ada sekitar setengah juta sintaks regex yang berbeda; mereka tampaknya datang ke Perl, EMACS / GNU, dan AT&T secara umum, tapi saya selalu terkejut juga.
sumber
Terkadang melarikan diri sederhana tidak dimungkinkan dengan karakter yang telah Anda daftarkan. Misalnya, menggunakan garis miring terbalik untuk keluar dari braket tidak akan bekerja di sisi kiri string pengganti dalam sed, yaitu
Saya cenderung hanya menggunakan definisi kelas karakter sederhana saja, jadi ungkapan di atas menjadi
yang saya temukan berfungsi untuk sebagian besar implementasi regexp.
Kelas-kelas BTW Character adalah komponen vanilla regexp yang cantik sehingga mereka cenderung bekerja di sebagian besar situasi di mana Anda perlu karakter yang lolos dalam regexps.
Sunting: Setelah komentar di bawah, hanya berpikir saya akan menyebutkan fakta bahwa Anda juga harus mempertimbangkan perbedaan antara automata keadaan terbatas dan automata keadaan tidak terbatas ketika melihat perilaku evaluasi regexp.
Anda mungkin ingin melihat "buku bola mengkilap" alias Efektif Perl ( sanitized Amazon link ), khususnya bab tentang ekspresi reguler, untuk merasakan perbedaan dalam jenis evaluasi mesin regexp.
Tidak semua PCRE di dunia!
Bagaimanapun, regexp sangat kikuk dibandingkan dengan SNOBOL ! Nah , itu kursus pemrograman yang menarik! Seiring dengan yang ada di Simula .
Ah kegembiraan belajar di UNSW di akhir 70-an! (-:
sumber
Untuk PHP, "selalu aman untuk mengawali non-alfanumerik dengan" \ "untuk menentukan bahwa itu adalah singkatan dari itu sendiri." - http://php.net/manual/en/regexp.reference.escape.php .
Kecuali jika itu "atau '.: /
Untuk keluar dari variabel pola regex (atau variabel parsial) di PHP, gunakan preg_quote ()
sumber
Untuk mengetahui kapan dan apa yang harus dihindari tanpa upaya diperlukan untuk memahami dengan tepat rantai konteks yang dilalui oleh string. Anda akan menentukan string dari sisi terjauh ke tujuan akhirnya yang merupakan memori yang ditangani oleh kode parsing regexp.
Waspadai bagaimana string dalam memori diproses: jika bisa berupa string polos di dalam kode, atau string yang dimasukkan ke baris perintah, tetapi bisa berupa baris perintah interaktif atau baris perintah yang dinyatakan di dalam file skrip shell, atau di dalam variabel dalam memori yang disebutkan oleh kode, atau argumen (string) melalui evaluasi lebih lanjut, atau string yang berisi kode yang dihasilkan secara dinamis dengan segala jenis enkapsulasi ...
Masing-masing konteks ini menetapkan beberapa karakter dengan fungsi khusus.
Ketika Anda ingin melewatkan karakter secara harfiah tanpa menggunakan fungsi khusus (lokal ke konteks), maka Anda harus menghindarinya, untuk konteks berikutnya ... yang mungkin memerlukan beberapa karakter pelarian lain yang mungkin juga perlu melarikan diri dalam konteks sebelumnya. Selain itu, ada hal-hal seperti pengkodean karakter (yang paling berbahaya adalah utf-8 karena terlihat seperti ASCII untuk karakter umum, tetapi dapat ditafsirkan secara opsional bahkan oleh terminal tergantung pada pengaturannya sehingga mungkin berperilaku berbeda, kemudian atribut pengkodean HTML / XML, perlu untuk memahami prosesnya dengan tepat.
Misalnya, regexp dalam baris perintah yang dimulai dengan
perl -npe
, perlu ditransfer ke satu set panggilan sistem exec yang menghubungkan file pipa, masing-masing panggilan sistem exec ini hanya memiliki daftar argumen yang dipisahkan oleh ruang (tidak lolos), dan mungkin pipa (|) dan pengalihan (> N> N> & M), kurung, ekspansi interaktif*
dan?
,$(())
... (semua ini adalah karakter khusus yang digunakan oleh * sh yang mungkin muncul untuk mengganggu karakter ekspresi reguler dalam konteks berikutnya, tetapi mereka dievaluasi dalam urutan: sebelum baris perintah. Baris perintah dibaca oleh memprogram sebagai bash / sh / csh / tcsh / zsh, pada dasarnya di dalam double quote atau single quote melarikan diri lebih sederhana tetapi tidak perlu untuk mengutip string di baris perintah karena sebagian besar ruang harus diawali dengan backslash dan kutipan tersebut tidak perlu meninggalkan tersedia memperluas fungsi untuk karakter * dan?, tapi ini menguraikan konteks yang berbeda seperti dalam kutipan. Kemudian ketika baris perintah dievaluasi regexp yang diperoleh dalam memori (tidak seperti yang tertulis dalam baris perintah) menerima perlakuan yang sama seperti itu akan berada dalam file sumber. Untuk regexp ada konteks karakter-set dalam tanda kurung [],perl ekspresi reguler dapat dikutip oleh sejumlah besar karakter non-alfa-numerik (Misalnya m // atau m: / better / for / path: ...).Anda memiliki detail lebih lanjut tentang karakter dalam jawaban lain, yang sangat spesifik untuk konteks regexp akhir. Seperti yang saya catat Anda menyebutkan bahwa Anda menemukan pelarian regexp dengan upaya, itu mungkin karena konteks yang berbeda memiliki serangkaian karakter yang membingungkan memori upaya Anda (sering backslash adalah karakter yang digunakan dalam konteks yang berbeda untuk melarikan diri dari karakter literal alih-alih fungsinya. ).
sumber
https://perldoc.perl.org/perlre.html#Quoting-metacharacters dan https://perldoc.perl.org/functions/quotemeta.html
Dalam dokumentasi resmi, karakter tersebut disebut metacharacters. Contoh mengutip:
sumber
Untuk Ionic (Skrip) Anda harus menggandakan garis miring untuk mencetak karakter. Misalnya (ini untuk mencocokkan beberapa karakter khusus):
Perhatikan
] [ - _ . /
karakter ini . Mereka harus dipotong ganda. Jika Anda tidak melakukan itu, Anda akan memiliki kesalahan ketik dalam kode Anda.sumber