Perspektif sejarah
Artikel Wikipedia cukup detail tentang asal mula ekspresi reguler (Kleene, 1956). Sintaks asli relatif sederhana dengan hanya *
, +
, ?
, |
dan pengelompokan (...)
. Itu singkat ( dan dapat dibaca, keduanya tidak perlu menentang), karena bahasa formal cenderung diekspresikan dengan notasi matematika singkat.
Kemudian, sintaks dan kapabilitas berevolusi dengan editor dan tumbuh dengan Perl , yang berusaha singkat dengan desain ( "konstruksi umum harus pendek" ). Ini banyak memperumit sintaksis, tetapi perhatikan bahwa orang sekarang terbiasa dengan ekspresi reguler dan pandai menulis (jika tidak membaca) mereka. Fakta bahwa mereka kadang-kadang hanya menulis menunjukkan bahwa ketika mereka terlalu panjang, mereka umumnya bukan alat yang tepat.
Ekspresi reguler cenderung tidak terbaca saat disalahgunakan.
Di luar ekspresi reguler berbasis string
Berbicara tentang sintaksis alternatif, mari kita lihat salah satu yang sudah ada ( cl-ppcre , di Common Lisp ). Ekspresi reguler panjang Anda dapat diuraikan ppcre:parse-string
sebagai berikut:
(let ((*print-case* :downcase)
(*print-right-margin* 50))
(pprint
(ppcre:parse-string "^(?:([A-Za-z]+):)?(\\/{0,3})(0-9.\\-A-Za-z]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$")))
... dan hasil dalam bentuk berikut:
(:sequence :start-anchor
(:greedy-repetition 0 1
(:group
(:sequence
(:register
(:greedy-repetition 1 nil
(:char-class (:range #\A #\Z)
(:range #\a #\z))))
#\:)))
(:register (:greedy-repetition 0 3 #\/))
(:register
(:sequence "0-9" :everything "-A-Za-z"
(:greedy-repetition 1 nil #\])))
(:greedy-repetition 0 1
(:group
(:sequence #\:
(:register
(:greedy-repetition 1 nil :digit-class)))))
(:greedy-repetition 0 1
(:group
(:sequence #\/
(:register
(:greedy-repetition 0 nil
(:inverted-char-class #\? #\#))))))
(:greedy-repetition 0 1
(:group
(:sequence #\?
(:register
(:greedy-repetition 0 nil
(:inverted-char-class #\#))))))
(:greedy-repetition 0 1
(:group
(:sequence #\#
(:register
(:greedy-repetition 0 nil :everything)))))
:end-anchor)
Sintaks ini lebih verbose, dan jika Anda melihat komentar di bawah ini, belum tentu lebih mudah dibaca. Jadi jangan berasumsi bahwa karena Anda memiliki sintaks yang kurang kompak, semuanya akan menjadi lebih jelas secara otomatis .
Namun, jika Anda mulai mengalami masalah dengan ekspresi reguler Anda, mengubahnya menjadi format ini dapat membantu Anda menguraikan dan men-debug kode Anda. Ini adalah salah satu keunggulan dibandingkan format berbasis string, di mana kesalahan satu karakter bisa sulit dikenali.
Keuntungan utama sintaks ini adalah memanipulasi ekspresi reguler menggunakan format terstruktur alih-alih pengkodean berbasis string. Itu memungkinkan Anda untuk membuat dan membangun ekspresi seperti itu seperti struktur data lainnya di program Anda. Ketika saya menggunakan sintaks di atas, ini umumnya karena saya ingin membangun ekspresi dari bagian yang lebih kecil (lihat juga jawaban CodeGolf saya ). Sebagai contoh Anda, kami dapat menulis 1 :
`(:sequence
:start-anchor
,(protocol)
,(slashes)
,(domain)
,(top-level-domain) ... )
Ekspresi reguler berbasis string juga dapat dikomposisikan, menggunakan penggabungan string dan atau interpolasi yang dibungkus dengan fungsi helper. Namun, ada keterbatasan dengan manipulasi string yang yang cenderung kekacauan yang kode (berpikir tentang masalah bersarang, tidak seperti backticks vs $(...)
di bash, juga, melarikan diri karakter dapat memberikan sakit kepala).
Perhatikan juga bahwa formulir di atas memungkinkan (:regex "string")
formulir sehingga Anda dapat mencampur notasi singkat dengan pohon. Semua itu mengarah IMHO ke keterbacaan dan kompabilitas yang baik; ini membahas tiga masalah yang diungkapkan oleh delnan , secara tidak langsung (yaitu tidak dalam bahasa ekspresi reguler itu sendiri).
Untuk menyimpulkan
Untuk sebagian besar tujuan, notasi singkat ini sebenarnya dapat dibaca. Ada kesulitan ketika berhadapan dengan notasi tambahan yang melibatkan backtracking, dll., Tetapi penggunaannya jarang dibenarkan. Penggunaan ekspresi reguler yang tidak beralasan dapat menyebabkan ekspresi yang tidak dapat dibaca.
Ekspresi reguler tidak perlu dikodekan sebagai string. Jika Anda memiliki perpustakaan atau alat yang dapat membantu Anda membangun dan menulis ekspresi reguler, Anda akan menghindari banyak bug potensial yang terkait dengan manipulasi string.
Atau, tata bahasa formal lebih mudah dibaca dan lebih baik dalam penamaan dan abstrak sub-ekspresi. Terminal umumnya dinyatakan sebagai ekspresi reguler sederhana.
1. Anda mungkin lebih suka untuk membangun ekspresi Anda pada waktu-baca, karena ekspresi reguler cenderung konstan dalam aplikasi. Lihat create-scanner
dan load-time-value
:
'(:sequence :start-anchor #.(protocol) #.(slashes) ... )