Ketika menjelajahi ekspresi reguler (atau dikenal sebagai RegEx-es), ada banyak individu yang tampaknya melihat ekspresi reguler sebagai Cawan Suci. Sesuatu yang terlihat sangat rumit - harus menjadi jawaban untuk setiap pertanyaan. Mereka cenderung berpikir bahwa setiap masalah dapat diselesaikan dengan menggunakan ekspresi reguler.
Di sisi lain, ada juga banyak orang yang mencoba menghindari ekspresi reguler dengan cara apa pun. Mereka mencoba mencari jalan keluar di sekitar ekspresi reguler dan menerima pengkodean tambahan hanya untuk kepentingan itu, bahkan jika ekspresi reguler akan menjadi solusi yang lebih kompak.
Mengapa ekspresi reguler dianggap sangat kontroversial? Apakah ada kesalahpahaman yang tersebar luas tentang cara kerjanya? Atau mungkinkah keyakinan luas bahwa ekspresi reguler pada umumnya lambat?
Jawaban:
Saya tidak berpikir orang keberatan dengan ekspresi reguler karena mereka lambat, tetapi lebih karena mereka sulit dibaca dan ditulis, dan juga sulit untuk diperbaiki. Meskipun ada beberapa situasi di mana ekspresi reguler memberikan solusi yang efektif dan ringkas untuk masalah tersebut, terkadang ekspresi tersebut disuntikkan ke dalam situasi di mana lebih baik menggunakan bagian kode yang mudah dibaca dan dikelola.
sumber
|
atau.*
), karena mereka menggunakan mesin stack dan backtracking. Itu sebabnya Anda harus hati-hati menyetel ekspresi reguler Anda di Perl, Java, Python, Ruby ... Mesin ekspresi reguler gaya lama (grep
misalnya, dalam kompilasi) mengkompilasi pola menjadi DFA. Setelah itu, kompleksitas pola sebagian besar tidak relevan. Saya hanya menggunakan Java dan grep untuk teks dan pola yang sama: 22 menit vs 2s. Inilah sainsnya: swtch.com/~rsc/regexp/regexp1.htmlMembuat Regex Dapat Dipertahankan
Kemajuan besar menuju demistifikasi pola yang sebelumnya disebut sebagai "ekspresi reguler" adalah
/x
bendera regex Perl - terkadang ditulis(?x)
ketika disematkan - yang memungkinkan spasi putih (pemutusan baris, indentasi) dan komentar. Ini secara serius meningkatkan keterbacaan dan karenanya pemeliharaan. Ruang putih memungkinkan untuk chunking kognitif, sehingga Anda dapat melihat kelompok apa dengan apa.Pola-pola modern sekarang juga mendukung referensi yang relatif bernomor dan dinamai sekarang. Itu berarti Anda tidak lagi perlu menghitung kelompok tangkap untuk mengetahui bahwa Anda membutuhkan
$4
atau\7
. Ini membantu saat membuat pola yang dapat dimasukkan dalam pola selanjutnya.Ini adalah contoh kelompok penangkapan yang relatif bernomor:
Dan di sini adalah contoh dari pendekatan superior dari tangkapan bernama:
Regex Tata Bahasa
Yang terbaik dari semuanya , tangkapan yang dinamai ini dapat ditempatkan di dalam satu
(?(DEFINE)...)
blok, sehingga Anda dapat memisahkan deklarasi dari eksekusi elemen-elemen yang disebut individual dari pola Anda. Ini membuat mereka bertindak seperti subrutin dalam pola.Contoh yang bagus dari "regex gramatikal" semacam ini dapat ditemukan dalam jawaban ini dan yang ini . Ini lebih mirip deklarasi gramatikal.
Saat yang terakhir mengingatkan Anda:
Ini tidak bisa terlalu ditekankan. Tentu saja jika Anda tidak menggunakan hal-hal itu dalam pola Anda, Anda akan sering membuat mimpi buruk. Tapi jika Anda lakukan menggunakan mereka, meskipun, Anda tidak perlu.
Berikut adalah contoh lain dari pola tata bahasa modern, yang ini untuk parsing RFC 5322: gunakan 5.10.0;
Bukankah itu luar biasa - dan indah? Anda dapat menggunakan tata bahasa gaya BNF dan menerjemahkannya langsung ke dalam kode tanpa kehilangan struktur dasarnya!
Jika pola tata bahasa modern masih belum cukup bagi Anda, maka modul brilian Damian Conway
Regexp::Grammars
menawarkan sintaks yang lebih bersih, dengan debugging yang unggul juga. Berikut kode yang sama untuk mem-parsing RFC 5322 menyusun kembali ke dalam pola dari modul itu:Ada banyak hal yang baik di dalam perlre manualnya , tapi ini perbaikan dramatis dalam fitur desain regex mendasar adalah tidak berarti terbatas pada Perl saja. Memang yang pcrepattern manualnya mungkin menjadi membaca lebih mudah, dan mencakup wilayah yang sama.
Pola modern hampir tidak memiliki kesamaan dengan hal-hal primitif yang Anda ajarkan di kelas automata terbatas Anda.
sumber
/x
. Ini menggunakan(?&name)
regex secara tata bahasa, dengan subrutin regex internal, yang benar-benar membuat ini bersinar.re.VERBOSE
bendera.Regex adalah alat yang hebat, tetapi orang-orang berpikir, "Hei, alat yang hebat, saya akan menggunakannya untuk melakukan X!" di mana X adalah sesuatu yang lebih baik untuk alat yang berbeda (biasanya parser). Ini adalah standar menggunakan palu di mana Anda memerlukan masalah obeng.
sumber
split($pattern,$string)
vsexplode($delimiter,$string)
- untungnya yang pertama semakin terdepresiasi, tetapi banyak kode menggunakan yang pertama ketika mereka hanya membutuhkan kekuatan nanti. Aggreed, RegEx's menyediakan alat yang mudah untuk melakukan beberapa hal tetapi kecuali jika Anda membutuhkan kekuatan penuh dari ekspresi reguler merekaHampir semua orang yang saya kenal yang menggunakan ekspresi reguler secara teratur (pun intended) berasal dari latar belakang Unix-ish di mana mereka menggunakan alat yang memperlakukan RE sebagai konstruksi pemrograman kelas satu, seperti grep, sed, awk, dan Perl. Karena hampir tidak ada overhead sintaksis untuk menggunakan ekspresi reguler, produktivitasnya naik ketika mereka melakukannya.
Sebaliknya, programmer yang menggunakan bahasa di mana RE adalah perpustakaan eksternal cenderung tidak mempertimbangkan ekspresi reguler apa yang dapat dibawa ke meja. Programmer "waktu-biaya" sangat tinggi sehingga a) RE tidak pernah muncul sebagai bagian dari pelatihan mereka, atau b) mereka tidak "berpikir" dalam hal RE dan memilih untuk kembali ke pola yang lebih akrab.
sumber
Ekspresi reguler memungkinkan Anda untuk menulis mesin finite-state custom (FSM) kustom dengan cara yang ringkas, untuk memproses serangkaian input. Setidaknya ada dua alasan mengapa menggunakan ekspresi reguler itu sulit:
Pengembangan perangkat lunak lama melibatkan banyak perencanaan, model kertas, dan pemikiran yang cermat. Ekspresi reguler cocok dengan model ini dengan sangat baik, karena menulis ekspresi efektif dengan benar melibatkan banyak menatapnya, memvisualisasikan jalur FSM.
Pengembang perangkat lunak modern lebih suka mengeluarkan kode, dan menggunakan debugger untuk melakukan eksekusi, untuk melihat apakah kode itu benar. Ekspresi reguler tidak mendukung gaya kerja ini dengan baik. Satu "pelarian" dari ekspresi reguler secara efektif adalah operasi atom. Sulit untuk mengamati eksekusi bertahap di debugger.
Terlalu mudah untuk menulis ekspresi reguler yang secara tidak sengaja menerima lebih banyak input daripada yang Anda inginkan. Nilai ekspresi reguler tidak benar-benar cocok dengan input yang valid, itu gagal mencocokkan input yang tidak valid . Teknik untuk melakukan "tes negatif" untuk ekspresi reguler tidak terlalu canggih, atau setidaknya tidak banyak digunakan.
Ini membuat ekspresi reguler sulit dibaca. Hanya dengan melihat ekspresi reguler, dibutuhkan banyak konsentrasi untuk memvisualisasikan semua input yang mungkin harus ditolak, tetapi diterima secara keliru. Pernah mencoba men-debug kode ekspresi reguler orang lain ?
Jika ada penolakan untuk menggunakan ekspresi reguler di antara pengembang perangkat lunak hari ini, saya pikir itu terutama karena kedua faktor ini.
sumber
Orang cenderung menganggap ekspresi reguler itu sulit; tapi itu karena mereka salah menggunakannya. Menulis satu kalimat yang rumit tanpa komentar, indentasi atau tangkapan bernama. (Anda tidak menjejalkan ekspresi SQL kompleks Anda dalam satu baris, tanpa komentar, indentasi atau alias, kan?). Jadi ya, bagi banyak orang, itu tidak masuk akal.
Namun, jika pekerjaan Anda ada hubungannya dengan parsing teks (kira-kira semua aplikasi web di luar sana ...) dan Anda tidak tahu ekspresi reguler, Anda payah pada pekerjaan Anda dan Anda membuang-buang waktu Anda sendiri dan bahwa Anda majikan. Ada sumber daya yang sangat bagus di luar sana untuk mengajari Anda segala sesuatu tentang mereka yang perlu Anda ketahui, dan banyak lagi.
sumber
x
pengubah untuk regex yang menyebabkan spasi kosong diabaikan. Ini memungkinkan Anda untuk meletakkan regex pada beberapa baris dan menambahkan komentar.re.X
aliasre.VERBOSE
.x
modifikator di tcl. Saya percaya ini cukup standar karena tcl, tidak seperti bahasa lain, tidak menggunakan PCRE.Karena mereka tidak memiliki alat belajar paling populer di IDE yang diterima secara umum: Tidak ada Regex Wizard. Bahkan Pelengkapan Otomatis. Anda harus mengkodekan semuanya sendirian.
sumber
()
, persegi[]
, atau keriting{}
. Ini juga akan bekerja dengan backslash." Ekspresi Reguler: Sekarang Anda Memiliki Dua Masalah " adalah artikel hebat dari Jeff Atwood tentang masalah ini. Pada dasarnya, ekspresi reguler "keras"! Mereka dapat menciptakan masalah baru. Namun mereka efektif.
sumber
Saya tidak berpikir mereka begitu kontroversial.
Saya juga berpikir Anda sudah semacam menjawab pertanyaan Anda sendiri, karena Anda menunjukkan betapa konyolnya menggunakannya di mana-mana ( Tidak semuanya adalah bahasa biasa 2 ) atau untuk tidak menggunakannya sama sekali. Anda, sang programmer, harus membuat keputusan yang cerdas tentang kapan ekspresi reguler akan membantu kode atau merusaknya. Ketika dihadapkan dengan keputusan seperti itu, dua hal penting yang perlu diingat adalah rawatan (yang menyiratkan keterbacaan) dan ekstensibilitas.
Bagi mereka yang sangat menentang mereka, tebakan saya adalah bahwa mereka tidak pernah belajar menggunakannya dengan benar. Saya pikir kebanyakan orang yang menghabiskan hanya beberapa jam dengan tutorial yang layak akan mencari tahu mereka dan menjadi lancar dengan sangat cepat. Inilah saran saya untuk mulai dari mana:
http://docs.python.org/howto/regex
Meskipun halaman itu berbicara tentang ekspresi reguler dalam konteks Python, saya menemukan informasi ini sangat berlaku di tempat lain. Ada beberapa hal yang spesifik-Python, tapi saya yakin mereka jelas dicatat, dan mudah diingat.
sumber
Ekspresi reguler untuk string apa operator aritmatika untuk angka, dan saya tidak akan menganggap mereka kontroversial. Saya pikir bahkan seorang aktivis OO yang cukup militan seperti saya (yang akan cenderung memilih objek lain daripada string) akan sulit ditekan untuk menolaknya.
sumber
Masalahnya adalah bahwa regex berpotensi sangat kuat sehingga Anda dapat melakukan sesuatu dengan mereka sehingga Anda harus menggunakan sesuatu yang berbeda.
Seorang programmer yang baik harus tahu di mana menggunakannya, dan di mana tidak. Contoh khas adalah parsing bahasa non-reguler (lihat Memutuskan apakah suatu bahasa biasa ).
Saya pikir Anda tidak dapat salah jika pada awalnya Anda membatasi diri pada ekspresi reguler yang sebenarnya (tanpa ekstensi). Beberapa ekstensi dapat membuat hidup Anda sedikit lebih mudah, tetapi jika Anda menemukan sesuatu yang sulit untuk diungkapkan sebagai regex nyata , ini mungkin merupakan indikasi bahwa regex bukanlah alat yang tepat.
sumber
Anda mungkin juga bertanya mengapa goto kontroversial.
Pada dasarnya, ketika Anda mendapatkan begitu banyak kekuatan "jelas", orang cenderung menyalahgunakan mereka untuk situasi yang bukan pilihan terbaik mereka. Jumlah orang yang meminta parse CSV atau XML atau HTML di regex, misalnya, mengejutkan saya. Ini alat yang salah untuk pekerjaan itu. Tetapi beberapa pengguna tetap bersikeras menggunakan regex.
Secara pribadi, saya mencoba untuk menemukan bahwa regex yang menggunakan sedang untuk apa yang baik untuk mereka, dan menghindarinya ketika mereka kurang optimal.
Perhatikan bahwa regex masih dapat digunakan untuk mem-parsing CSV, XML, HTML, dll. Tetapi biasanya tidak dalam satu regex.
sumber
Saya tidak berpikir "kontroversial" adalah kata yang tepat.
Tetapi saya telah melihat banyak contoh di mana orang mengatakan "apa ekspresi reguler yang perlu saya lakukan manipulasi string ini-dan-itu?" yang merupakan masalah XY.
Dengan kata lain, mereka mulai dari asumsi bahwa regex adalah apa yang mereka butuhkan, tetapi mereka akan lebih baik dengan split (), terjemahan seperti tr tr's /// di mana karakter diganti satu dengan yang lain, atau hanya sebuah indeks ().
sumber
Ini adalah topik yang menarik.
Banyak penggemar regexp tampaknya membingungkan keringkasan formula dengan efisiensi.
Selain itu, regexp yang membutuhkan banyak pemikiran menghasilkan kepuasan besar bagi pengarangnya yang membuatnya langsung sah.
Tapi ... regexps sangat nyaman ketika kinerja bukan masalah dan Anda harus berurusan dengan cepat dengan output teks, misalnya di Perl. Juga, sementara kinerja adalah masalah, orang mungkin memilih untuk tidak mencoba mengalahkan perpustakaan regexp dengan menggunakan algoritma buatan sendiri yang mungkin buggy atau kurang efisien.
Selain itu ada sejumlah alasan mengapa regexps dikritik secara tidak adil, misalnya
sumber
Apa yang saya pikirkan adalah Mempelajari Regex dan mempertahankan regex menjadi tidak populer, sebagian besar pengembangnya malas atau kebanyakan dari mereka bergantung pada perpustakaan eksternal untuk melakukan parsing untuk mereka ... mereka bergantung pada google untuk jawabannya dan bahkan bertanya di forum untuk kode lengkap untuk masalah mereka. Tetapi ketika datang untuk mengimplementasikan atau memodifikasi / memelihara regex mereka hanya gagal.
Ada pepatah populer "Teman jangan biarkan Teman menggunakan Regex untuk Parsing HTML"
Tetapi sejauh yang saya ketahui, saya telah membuat parser HTML lengkap menggunakan Regex dan saya menemukan diri saya bahwa regex lebih baik dalam mengurai string html baik dari segi kecepatan maupun dari segi memori (jika Anda memiliki Ide apa yang ingin Anda capai :))
sumber
Ekspresi reguler adalah misteri serius bagi banyak orang, termasuk saya. Ini bekerja dengan baik tetapi itu seperti melihat persamaan matematika. Saya senang melaporkan bahwa seseorang akhirnya telah membuat lokasi gabungan berbagai fungsi ekspresi reguler di http://regexlib.com/ . Sekarang jika Microsoft hanya akan membuat kelas ekspresi reguler yang secara otomatis akan melakukan banyak hal umum seperti menghilangkan huruf, atau memfilter tanggal.
sumber
Saya menemukan ekspresi reguler sangat berharga pada waktu-waktu tertentu. Ketika saya perlu melakukan beberapa pencarian "fuzzy", dan mungkin menggantikan. Ketika data dapat bervariasi dan memiliki keacakan tertentu. Namun, ketika saya perlu melakukan pencarian dan penggantian sederhana, atau memeriksa string, saya tidak menggunakan ekspresi reguler. Meskipun saya tahu banyak orang yang melakukannya, mereka menggunakannya untuk semuanya. Itu adalah kontroversi.
Jika Anda ingin meletakkan paku di dinding, jangan gunakan palu. Ya, itu akan berhasil, tetapi pada saat Anda mendapatkan palu, saya bisa meletakkan 20 paku payung di dinding.
Ekspresi reguler harus digunakan untuk apa mereka dirancang, dan tidak kurang.
sumber
Sementara saya pikir regex adalah alat yang penting, hal yang paling menjengkelkan tentang mereka adalah bahwa ada implementasi yang berbeda. Sedikit perbedaan dalam sintaksis, pengubah, dan -terutama- "keserakahan" dapat membuat segalanya benar-benar kacau, membutuhkan trial-and-error dan terkadang menghasilkan bug yang membingungkan.
sumber
Dalam beberapa kasus saya pikir Anda HARUS menggunakannya. Misalnya untuk membangun lexer.
Menurut pendapat saya, ini adalah sudut pandang orang yang dapat menulis regexp dan orang yang tidak (atau sulit). Saya kira ini adalah pemikiran yang bagus misalnya untuk memvalidasi input formulir, baik itu dalam javascript untuk memperingatkan pengguna, atau dalam bahasa sisi server.
sumber
Saya pikir ini adalah teknik yang kurang dikenal di kalangan programmer. Jadi, tidak ada penerimaan yang luas untuk itu. Dan jika Anda memiliki manajer non-teknis untuk meninjau kode Anda atau meninjau pekerjaan Anda maka ekspresi reguler sangat buruk. Anda akan menghabiskan berjam-jam menulis ekspresi reguler yang sempurna, dan Anda akan mendapatkan beberapa nilai untuk modul karena dia telah menulis begitu sedikit baris kode. Juga, seperti yang dikatakan di tempat lain, membaca ekspresi reguler adalah tugas yang sangat sulit.
sumber
Sistem ekspresi reguler yang layak seperti yang digunakan dalam lex dan yacc untuk definisi kompiler bagus, sangat berguna dan bersih. Dalam sistem ini, tipe ekspresi didefinisikan dalam istilah orang lain. Ekspresi reguler satu-liner garis-derau malformasi mengerikan yang tidak terbaca yang biasa ditemukan dalam kode perl dan sed (dll) yang 'kontroversial' (sampah).
sumber
Penggunaan regex terbaik yang valid dan normal adalah untuk validasi format alamat email.
Itu aplikasi yang bagus.
Saya telah menggunakan ekspresi reguler berulang kali sebagai one-off di TextPad untuk memijat file datar, membuat file csv, membuat pernyataan penyisipan SQL dan hal-hal semacam itu.
Ekspresi reguler yang ditulis dengan baik tidak boleh terlalu lambat. Biasanya alternatif, seperti banyak panggilan untuk Ganti adalah opsi yang jauh lebih lambat. Mungkin juga melakukannya dalam satu pass.
Banyak situasi membutuhkan ekspresi yang tepat dan tidak ada yang lain.
Mengganti karakter non-cetak khusus dengan karakter tidak berbahaya adalah penggunaan lain yang baik.
Tentu saja saya bisa membayangkan bahwa ada beberapa basis kode yang terlalu sering menggunakan ekspresi reguler sehingga merugikan pemeliharaan. Saya belum pernah melihat itu sendiri. Saya sebenarnya telah dihalangi oleh pengulas kode karena tidak cukup menggunakan ekspresi reguler.
sumber