Ekspresi reguler yang berfungsi “di mana saja”
(johndcook.com)- Ekspresi reguler memiliki fitur dan sintaks yang berbeda di tiap implementasi, sehingga pola yang berjalan di satu alat bisa gagal atau perlu diubah di lingkungan lain
- Semakin terbiasa dengan lingkungan yang kaya fitur seperti Perl, semakin sering menemui masalah kompatibilitas, dan jika harus mempertimbangkan komputer tanpa hak instalasi, lebih aman memakai subset bersama
- Jika “di mana saja” didefinisikan seketat mungkin, cakupannya menyempit hingga praktis hanya menyisakan literal, kelas karakter
[…], dan karakter spesial dasar seperti. * ^ $ - Jika memakai GNU
sed,awk,grepserta opsi-Epadaseddangrep, fitur bersama yang bisa dimanfaatkan menjadi lebih luas, tetapi dalam kombinasi iniawkumumnya menjadi penyebut umum terkecil - Emacs memerlukan backslash untuk
+? ( ) { } |, dan makna\\s,\\Sjuga berbeda, jadi jika ingin memakai regex yang sama di beberapa alat, perlu memeriksa sampai ke sintaks pengecualian
Mengapa kompatibilitas ekspresi reguler itu sulit
- Ketidaknyamanan terbesar dari ekspresi reguler berasal dari perbedaan antarimplementasi
- Fitur yang didukung di satu alat bisa sama sekali tidak ada di alat lain
- Bahkan untuk fitur yang sama, sintaksnya bisa sedikit berbeda
- Perl adalah lingkungan regex yang kaya fitur, sehingga fitur yang tampak wajar jika berpatokan pada Perl kadang hilang di lingkungan lain
- Ada juga cara memakai pengganti mirip Perl di alat lain, tetapi itu tidak standar, sehingga sulit mengirim kode yang bisa langsung dijalankan oleh rekan kerja atau pelanggan
- Jika mempertimbangkan situasi ketika harus bekerja di komputer tempat kita tidak bisa memasang perangkat lunak, diperlukan pendekatan untuk mencari subset fitur regex yang berjalan di berbagai lingkungan
- Semakin ketat definisi “di mana saja”, semakin sedikit fitur yang bisa digunakan
- literal
- kelas karakter
[…] - karakter spesial
. * ^ $
Cakupan bersama di sed, awk, grep, dan Emacs
- Jika alat yang dituju dibatasi pada
sed,awk,grep, dan Emacs, standar “di mana saja” bisa dibuat sedikit lebih longgar - Jika memakai versi GNU dari
sed,awk,grepdan menerapkan opsi-Epadaseddangrep, daftar fitur bersama menjadi lebih luas- Fitur regex dari ketiga alat tersebut mirip
- Fitur
awkumumnya juga didukung di alat lain - Sebagai pengecualian, batas kata di
awkmemakai\\<,\\>dan berbeda dari\\b,\\B
- Emacs mendukung sebagian besar fitur
awk, tetapi ada perbedaan sintaks- Agar
+ ? ( ) { } |berfungsi seperti diawk, harus diberi backslash di depannya - Ekspresi yang setara dengan
\\s,\\Smilikawkdi Emacs adalah\\s-,\\S-
- Agar
- Di Emacs,
\\s,\\Stidak berarti spasi/nonspasi, melainkan memulai kelas karakter- Kelas
-berarti spasi \\s.adalah karakter tanda baca\\S.adalah karakter bukan tanda baca
- Kelas
- Berdasarkan kriteria ini, fitur yang dapat digunakan adalah sebagai berikut
.^,$[…],[^…]*\\w,\\W,\\s,\\S- Backreference dari
\\1sampai\\9 \\b,\\B?,+- alternatif
| - jumlah pengulangan
{n,m} - penangkapan
(...)
- Namun,
gawkmendukung backreference dalam string penggantian, tetapi tidak mendukung backreference di regex itu sendiri look-aroundbisa dianggap fitur lanjutan, dan\\dmungkin tampak seperti fitur dasar untuk angka, tetapi banyak varian regex tidak mendukungnya
1 komentar
Komentar Hacker News
Di Emacs, saya terutama kesulitan karena rasanya hampir seperti menebak-nebak apa saja yang harus di-escape
Memang ada alternatif bernama
rx[0], tetapi dalam praktiknya tidak terlalu menyenangkan dipakaiDi luar sintaks regex itu sendiri, masalah encoding dan escaping juga sering muncul pada tahap penggunaan nyata
Misalnya saat memasukkan regex di shell, kita harus meng-escape dengan benar, dan di Python harus memastikan apakah itu raw string
Meski begitu, fakta bahwa cara memakai regex di sebagian besar tool kini berada dalam rentang yang kurang lebih mirip terasa hampir seperti keajaiban modern
[0]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Rx...
Situasi dengan aturan escaping yang berbeda-beda yang saling bertumpuk terus bermunculan
(dan)dicocokkan secara literal terasa sedikit praktisPenulisnya tampak hampir sampai pada poin itu, tetapi pada akhirnya sepertinya ingin mengatakan bahwa POSIX basic regular expression berjalan di mana saja
Namun ada catatan bahwa belum semua orang mengejar Single Unix Specification edisi ke-8, dan pada edisi itu BRE sedikit berubah
Kalau tidak ada catatan seperti itu, sejak awal tulisan tersebut juga tidak perlu ditulis
Dulu saya pernah menulis makalah tentang mencari regex yang cocok dengan cara yang sama baik dalam semantik greedy maupun semantik leftmost maximal
https://par.nsf.gov/servlets/purl/10534654
Saya selalu bersikap cerewet soal memperjelas tool mana menerima bahasa regex yang mana, serta apa yang dicocokkan: substring sembarang, prefiks, sufiks, seluruh string, satu baris, atau substring di dalam baris
Di sini ada [yang lebih banyak dipakai][1], dan selain itu ada juga PCRE serta Python
Butuh waktu bagi saya untuk mengetahui bahwa sebagian format lama yang terlihat di tempat seperti grep [dispesifikasikan dalam POSIX][2]
[1]: https://cppreference.com/cpp/regex#Regular_expression_gramma...
[2]: https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd...
Saya ingin membagikan halaman regex dari Russ Cox
Menurut saya itu materi yang bagus untuk dibaca
https://swtch.com/~rsc/regexp/
Karena alasan seperti ini, RFC 9485, I-Regexp: An Interoperable Regular Expression Format, menjadi penting
https://datatracker.ietf.org/doc/html/rfc9485
Paket regexp di pustaka standar Go memakai engine RE2, sehingga tidak mendukung backreference
Bisa dipakai dalam substitusi, tetapi tidak untuk matching
regexpbukan memakai re2, melainkan implementasi terpisah dari konsep yang samaSetelah mengalami frustrasi serupa dengan rule engine, template engine, dan engine sejenis IFTTT, saya membuat library Rust untuk JSONLogic, dan juga menggunakan binding untuk bahasa lain
https://github.com/GoPlasmatic/datalogic-rs
Dokumen JSON Schema juga memiliki subset regex yang direkomendasikan
https://json-schema.org/understanding-json-schema/reference/...