Mengomentari ekspresi reguler


11

Apakah ada praktik umum untuk mengomentari ekspresi reguler: komentar inline merujuk bagian berbeda dari RegEx atau komentar umum untuk semua ekspresi?


2
Ada tetapi Anda harus lebih spesifik. Misalnya Bash mendukung komentar sebaris dan Python menawarkan ekspresi reguler verbose.
sakisk

6
Aturan praktis saya untuk ekspresi reguler adalah: jika Anda perlu mengomentari ekspresi reguler, itu terlalu rumit.
zzzzBov

1
Dan selalu sertakan tautan ini: regexcrossword.com
Kieveli

Saya tidak perlu setuju bahwa jika Anda harus berkomentar, itu terlalu rumit. Regex yang rumit masih bisa menghemat banyak kode penting Anda. Gunakan nama variabel deskriptif yang baik untuk menetapkan regex. Jika masih belum cukup jelas, gunakan komentar singkat untuk menyampaikan maksud asli di balik ekspresi reguler.
Craig

Jawaban:


10

Dalam pandangan saya, praktik yang baik adalah dengan singkat menyatakan dalam komentar apa gagasan umum dari ekspresi reguler itu. Ini menyelamatkan pengembang lain (atau terkadang Anda sendiri) kesulitan menyalin-menempelkan regex dalam pengurai seperti RegExr , hanya untuk memahami apa fungsinya.


2
Lagipula RegExr akan terjadi, kecuali dev adalah regex savant. Tetapi saya setuju dengan memberikan gambaran umum; itulah yang saya lakukan dengan regex saya.
Robert Harvey

3
+1: Apa pun yang lebih terperinci akan berakhir sebagai kursus kilat di regex sebagai komentar.
Matt

Jawaban ini dan komentar @zzzzBov masuk akal.
m0nhawk

1
Tidak hanya menghemat kerumitan pemeriksaan ekspresi reguler yang biasa untuk memahaminya, tetapi juga membuat maksud dari programmer asli menjadi jelas, terutama mengingat kemungkinan yang berbeda bahwa programmer asli mendapatkan ekspresi reguler itu sendiri salah pada putaran waktu pertama. Karena itu, dalam banyak kasus menugaskan regex ke nama variabel yang baik dapat dihitung jauh ke arah menyediakan dokumentasi niat yang memadai.
Craig

9

Ini agak merupakan jawaban khusus bahasa, tetapi tidak ada bahasa yang disebutkan dalam pertanyaan.

Buku "Dive Into Python" menyarankan penerapan komentar menggunakan Verbose Regular Expressions :

Python memungkinkan Anda melakukan ini dengan sesuatu yang disebut ekspresi reguler verbose. Ekspresi reguler verbose berbeda dari ekspresi reguler kompak dalam dua cara:

  • Spasi diabaikan. Spasi, tab, dan carriage return tidak cocok dengan spasi, tab, dan carriage return. Mereka sama sekali tidak cocok. (Jika Anda ingin mencocokkan spasi dalam ekspresi reguler verbose, Anda harus menghindarinya dengan meletakkan backslash di depannya.)
  • Komentar diabaikan. Sebuah komentar dalam ekspresi reguler verbose sama seperti komentar dalam kode Python: dimulai dengan #karakter dan berlanjut hingga akhir baris. Dalam hal ini, ini adalah komentar dalam string multi-baris alih-alih dalam kode sumber Anda, tetapi berfungsi dengan cara yang sama.

Contoh:

>>> pattern = """
^                   # beginning of string
M{0,4}              # thousands - 0 to 4 M's
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                    #            or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                    #        or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                    #        or 5-8 (V, followed by 0 to 3 I's)
$                   # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE)                1

Sumber dan detail lebih lanjut di sini

Metode ini memiliki sedikit kerugian bahwa pemanggil harus tahu bahwa pola ditulis dalam format verbose dan menyebutnya sesuai.


2
Daripada menyimpan pola dalam suatu variabel, Anda dapat menggunakan re.compilepada titik di mana Anda mendefinisikan pola Anda, dan hanya menyimpan objek yang dihasilkan. Dengan begitu, flag kompilasi pola (termasuk re.VERBOSE) tidak perlu dipisahkan dari pola itu sendiri.
John Bartholomew

Jawaban yang sangat membantu, terima kasih! Tetapi bagaimana saya bisa mencocokkan dengan #jika saya menggunakan bendera verbose? Ngomong-ngomong: tautan sumber tampaknya sedang down.
winklerrr

Oke, jadi #dapat dicocokkan secara harfiah ketika di dalam kelas karakter: [#](sumber: docs.python.org/3/library/re.html#re.X )
winklerrr

8

Biasanya, saya akan menulis sebuah regex dan tidak menjelaskan masing-masing bagian dari regex, tetapi tujuannya. Itulah itu apa dan mengapa. Ini seperti bertanya, "Seperti apa komentar saya?" di mana orang akan berkata " Jangan menulis apa yang dilakukan kode, tulis mengapa kode melakukan apa yang dilakukannya "

// Strip the leading "?" and remove the query parameters "offset=<integer>" & "count=<integer> so we have a pattern of the request"          
var search = location.search.substring(1).replace(/offset=[0-9]+?&/g, "").replace(/count=[0-9]+?&/g, "");

Kecuali jika Anda mencoba untuk mengajarkan seseorang tentang regex melalui komentar dalam kode, saya tidak berpikir menjelaskan apa yang akan dilakukan masing-masing individu. Ketika bekerja dengan programmer lain, Anda dapat dengan aman berasumsi bahwa seseorang akan mengetahui sesuatu sebagai ekspresi reguler global.


3
Anda akan terkejut ...
Matt

6

Saya kira itu benar-benar tergantung pada bagaimana Anda menyatukan regex. Secara umum saya pikir itu akan menjadi ide yang buruk untuk memasukkan komentar dalam string regex yang sebenarnya itu sendiri (tidak mungkin dalam kebanyakan skenario, sejauh yang saya tahu). Jika Anda benar-benar perlu mengomentari bagian tertentu dari ekspresi reguler (apakah Anda mencoba untuk mengajar seseorang?), Kemudian pisahkan setiap potongan menjadi string terpisah pada baris mereka sendiri, dan komentar setiap baris menggunakan proses komentar normal untuk bahasa pemrograman Anda. Kalau tidak, jawaban pleinolijf cukup bagus.

contoh:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter

4

Saya biasanya mendefinisikan konstanta string yang namanya menggambarkan keseluruhan tujuan dari ekspresi reguler.

Sebagai contoh:

const string FloatingPointNumberPattern = @"[-+]?[0-9]*\.?[0-9]+";

Anda dapat menambahkan komentar di atas konstanta ini untuk memberikan deskripsi, tetapi biasanya nama konstan itu sendiri sudah cukup.


1
Satu hal tambahan yang saya sukai dari jawaban ini adalah bahwa jika digunakan di lebih dari satu tempat, maksudnya juga harus dibawa kemana-mana - tidak lupa untuk berkomentar.
J Trana

3

Dalam beberapa skenario, pengembang mungkin menggunakan ekspresi reguler untuk mencocokkan teks di luar domain tipikal mereka. Pengembang asli mungkin telah melalui banyak iterasi menangkap berbagai kasus tepi yang mungkin hanya ditemukan melalui proses iteratif. Dengan demikian, pengembang selanjutnya mungkin tidak menyadari banyak kasus tepi yang ditangani oleh pengembang asli, bahkan jika mereka mengetahui kasus umum.

Dalam kasus seperti ini, mungkin ada baiknya mendokumentasikan contoh variasi. Lokasi dokumentasi ini dapat bervariasi tergantung pada jumlah (mis., Tidak harus dalam kode).

Salah satu cara untuk mendekatinya adalah dengan mengasumsikan bahwa pengembang masa depan hanya akan memiliki pengetahuan dasar, seperti bagaimana ekspresi reguler bekerja, tetapi tidak ada pengetahuan yang Anda (1) miliki sebelum pengembangan ekspresi reguler yang tidak perlu diketahui oleh para pengembang. pengembang masa depan atau (2) pengetahuan yang Anda peroleh selama pengembangan (misalnya, kasus tepi yang ditemukan).

Misalnya, jika selama pengembangan Anda mengatakan sesuatu seperti "Oh, saya tidak tahu bahwa X dapat mengambil formulir ini," maka ada baiknya mendokumentasikannya (dan mungkin bagian dari regex yang menangani variasi itu).


2

Komentar harus menambahkan informasi bermanfaat yang tidak jelas dari kode.

  1. Buatlah mudah untuk memahami apa yang seharusnya dilakukan ekspresi pada tingkat persyaratan, baik dalam kode itu sendiri atau dalam komentar. Apa maksud di balik ungkapan itu, apakah untuk memvalidasi alamat email atau memilih nomor telepon Kanada.
  2. Buatlah mudah untuk memahami apa yang sebenarnya dilakukan ekspresi, yaitu untuk apa ekspresi itu dinilai. Pertama-tama cobalah untuk memperjelasnya dengan memisahkan ekspresi, jika Anda pertama-tama memeriksa semua tanda hubung kemudian menghapus semua angka kemudian membuat dua bagian ekspresi dengan variabel yang memegang nilai perantara, itu akan membuatnya lebih mudah dibaca dan pembaca akan mampu melewati logika Anda satu langkah pada satu waktu. (Ada jawaban terkenal untuk pertanyaan di SE di mana seseorang mencoba menguraikan beberapa kode lama yang melibatkan manipulasi bit '>>' dan mencari tahu apakah bendera tertentu ditetapkan di mana jawabannya menjabarkan tidak hanya apa kode sebenarnya tetapi juga bagaimana authour pertanyaan harus tentang mendekonstruksi kode semacam ini di masa depan yang persis apa yang saya coba gambarkan tetapi saya bisa '

Ada beberapa aplikasi yang membutuhkan setiap siklus terakhir, jika Anda pencocokan pola kumpulan data besar maka mungkin ada cara yang lebih baik, mungkin tidak, tetapi untuk sebagian besar hal waktu eksekusi tambahan bukan masalah besar.

Dan ingat orang berikutnya untuk menemukan kode Anda dan memperbaiki bug mungkin Anda dalam waktu enam bulan dan tidak ada cara Anda akan mengingat apa yang seharusnya dilakukan.


1

Ekstrak RegEx menjadi kelas yang terpisah menjadi dengan nama yang bermakna. Lalu saya akan mendokumentasikan kode dengan tes otomatis.

Ini akan memastikan

  • Bahwa kode tersebut benar-benar berfungsi - juga untuk kasing sudut
  • Pastikan "perbaikan bug" cepat tidak mengacaukan banyak kasus sudut
  • Dapat mendokumentasikan pengoptimalan saat pelacakan mundur dinonaktifkan

Secara alami, kelas Anda dapat menampung beberapa regex.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.