3 poin oleh GN⁺ 14 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • 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, grep serta opsi -E pada sed dan grep, fitur bersama yang bisa dimanfaatkan menjadi lebih luas, tetapi dalam kombinasi ini awk umumnya menjadi penyebut umum terkecil
  • Emacs memerlukan backslash untuk +? ( ) { } |, dan makna \\s, \\S juga 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, grep dan menerapkan opsi -E pada sed dan grep, daftar fitur bersama menjadi lebih luas
    • Fitur regex dari ketiga alat tersebut mirip
    • Fitur awk umumnya juga didukung di alat lain
    • Sebagai pengecualian, batas kata di awk memakai \\<, \\> dan berbeda dari \\b, \\B
  • Emacs mendukung sebagian besar fitur awk, tetapi ada perbedaan sintaks
    • Agar + ? ( ) { } | berfungsi seperti di awk, harus diberi backslash di depannya
    • Ekspresi yang setara dengan \\s, \\S milik awk di Emacs adalah \\s-, \\S-
  • Di Emacs, \\s, \\S tidak berarti spasi/nonspasi, melainkan memulai kelas karakter
    • Kelas - berarti spasi
    • \\s. adalah karakter tanda baca
    • \\S. adalah karakter bukan tanda baca
  • Berdasarkan kriteria ini, fitur yang dapat digunakan adalah sebagai berikut
    • .
    • ^, $
    • […], [^…]
    • *
    • \\w, \\W, \\s, \\S
    • Backreference dari \\1 sampai \\9
    • \\b, \\B
    • ?, +
    • alternatif |
    • jumlah pengulangan {n,m}
    • penangkapan (...)
  • Namun, gawk mendukung backreference dalam string penggantian, tetapi tidak mendukung backreference di regex itu sendiri
  • look-around bisa dianggap fitur lanjutan, dan \\d mungkin tampak seperti fitur dasar untuk angka, tetapi banyak varian regex tidak mendukungnya

1 komentar

 
GN⁺ 14 jam lalu
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 dipakai
    Di 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...

    • Menulis Python yang menghasilkan skrip shell berisi regex membuatnya jadi lebih menarik
      Situasi dengan aturan escaping yang berbeda-beda yang saling bertumpuk terus bermunculan
    • Kalau dipaksa mencari sisi positifnya, saat target pencarian adalah kode Elisp, fakta bahwa ( dan ) dicocokkan secara literal terasa sedikit praktis
    • Regex seharusnya menjadi bahasa yang terstruktur, bukan campuran berbagai DSL
  • Penulisnya 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

    • Penilaian itu tampaknya tidak adil bagi penulis
      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

    • regexp bukan memakai re2, melainkan implementasi terpisah dari konsep yang sama
  • Setelah 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/...