แสดงความคิดเห็นนิพจน์ปกติ


11

มีวิธีปฏิบัติทั่วไปในการแสดงความคิดเห็นนิพจน์ทั่วไปหรือไม่: ความคิดเห็นแบบอินไลน์อ้างอิงส่วนต่าง ๆ ของ RegEx หรือความคิดเห็นทั่วไปสำหรับการแสดงออกทั้งหมด?


2
มี แต่คุณจะต้องเฉพาะเจาะจงมากขึ้น ตัวอย่างเช่น Bash สนับสนุนความคิดเห็นแบบอินไลน์และ Python นำเสนอนิพจน์ทั่วไปแบบละเอียด
sakisk

6
กฎง่ายๆสำหรับฉันคือการแสดงออกถ้าคุณต้องการแสดงความคิดเห็นการแสดงออกปกติมันซับซ้อนเกินไป
zzzzBov

1
และรวมลิงค์นี้เสมอ: regexcrossword.com
Kieveli

ฉันไม่เห็นด้วยว่าถ้าคุณต้องแสดงความคิดเห็นมันซับซ้อนเกินไป regex ที่ซับซ้อนยังช่วยให้คุณประหยัดรหัสที่จำเป็นในการจ้องมอง ใช้ชื่อตัวแปรอธิบายที่ดีเพื่อกำหนด regex ให้ หากยังไม่ชัดเจนเพียงพอให้ใช้ความคิดเห็นสั้น ๆ เพื่อถ่ายทอดเจตนาดั้งเดิมที่อยู่เบื้องหลังการแสดงออกปกติ
Craig

คำตอบ:


10

ในทัศนะของฉันแนวทางปฏิบัติที่ดีคือการแสดงความคิดเห็นอย่างชัดเจนว่าแนวคิดทั่วไปของการแสดงออกปกติคืออะไร สิ่งนี้จะช่วยให้นักพัฒนาซอฟต์แวร์รายอื่น ๆ (หรือบางครั้งเป็นตัวคุณเอง) ความยุ่งยากในการคัดลอกวาง regex ในโปรแกรมแยกวิเคราะห์เช่นRegExrเพื่อทำความเข้าใจว่ามันทำอะไร


2
RegExr จะเกิดขึ้นต่อไปเว้นแต่ว่า dev จะเป็นผู้ชำนาญด้าน regex แต่ฉันเห็นด้วยกับการให้คำอธิบายทั่วไป นั่นคือสิ่งที่ฉันทำกับ regexes ของฉัน
Robert Harvey

3
+1: รายละเอียดเพิ่มเติมจะจบลงด้วยการเป็นหลักสูตรการชนใน regex เป็นความคิดเห็น
แมตต์

คำตอบนี้และความคิดเห็น @zzzzBov สมเหตุสมผลแล้ว
m0nhawk

1
ไม่เพียง แต่จะช่วยลดความยุ่งยากในการตรวจสอบการแสดงออกปกติเพื่อทำความเข้าใจ แต่มันทำให้เจตนาของโปรแกรมเมอร์ดั้งเดิมชัดเจนโดยเฉพาะอย่างยิ่งเมื่อมีความเป็นไปได้ที่ชัดเจนว่าโปรแกรมเมอร์ดั้งเดิมได้แสดงออกอย่างผิดปกติตลอดเวลา ต้องบอกว่าในหลายกรณีการกำหนด regex ให้เป็นชื่อตัวแปรที่ดีสามารถนับได้ว่าเป็นการจัดทำเอกสารแสดงเจตนาอย่างเพียงพอ
Craig

9

นี่เป็นคำตอบเฉพาะภาษา แต่ไม่มีภาษาระบุในคำถาม

หนังสือ"Dive Into Python"แนะนำการใช้ความคิดเห็นโดยใช้Verbose Regular Expressions :

Python ช่วยให้คุณทำสิ่งนี้ด้วยสิ่งที่เรียกว่าการแสดงออกปกติ verbose การแสดงออกปกติ verbose แตกต่างจากการแสดงออกปกติขนาดกะทัดรัดในสองวิธี:

  • ช่องว่างจะถูกละเว้น ช่องว่างแท็บและการขึ้นบรรทัดใหม่ไม่ตรงกับช่องว่างแท็บและการขึ้นบรรทัดใหม่ พวกเขาไม่ตรงเลย (หากคุณต้องการจับคู่ช่องว่างในนิพจน์ทั่วไปแบบละเอียดคุณจะต้องหลบหนีโดยใส่เครื่องหมายแบ็กสแลชไว้ด้านหน้า)
  • ความคิดเห็นจะถูกละเว้น ความคิดเห็นในการแสดงออกปกติ verbose เป็นเหมือนความคิดเห็นในรหัส Python มันเริ่มต้นด้วย#ตัวอักษรและไปจนถึงจุดสิ้นสุดของบรรทัด ในกรณีนี้มันเป็นความคิดเห็นภายในสตริงหลายบรรทัดแทนที่จะอยู่ในซอร์สโค้ดของคุณ แต่มันก็ทำงานในลักษณะเดียวกัน

ตัวอย่าง:

>>> 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

แหล่งที่มาและรายละเอียดเพิ่มเติมที่นี่

วิธีนี้มีข้อเสียเล็กน้อยที่ผู้เรียกต้องรู้ว่ารูปแบบนั้นเขียนในรูปแบบ verbose และเรียกมันตามนั้น


2
แทนที่จะเก็บรูปแบบในตัวแปรคุณสามารถใช้re.compileที่จุดที่คุณกำหนดรูปแบบของคุณและเก็บเฉพาะวัตถุที่เป็นผลลัพธ์ ด้วยวิธีนี้แฟล็กการรวบรวมรูปแบบ (รวมถึงre.VERBOSE) ไม่จำเป็นต้องถูกแยกออกจากรูปแบบเอง
John Bartholomew

คำตอบที่เป็นประโยชน์จริงๆขอบคุณ! แต่ฉันจะจับคู่#ถ้าฉันใช้ธง verbose ได้อย่างไร โดยวิธีการ: ลิงค์แหล่งที่มาดูเหมือนว่าจะลง
winklerrr

เอาล่ะ#สามารถจับคู่ได้อย่างแท้จริงเมื่ออยู่ในคลาสอักขระ: [#](แหล่งที่มา: docs.python.org/3/library/re.html#re.X )
winklerrr

8

โดยทั่วไปแล้วฉันจะเขียน regex และไม่อธิบายแต่ละส่วนของ regex แต่มันคือจุดประสงค์อะไร นั่นคือสิ่งที่และทำไม นี่เป็นคำถามที่ถามว่า "ความคิดเห็นของฉันควรเป็นอย่างไร" คนที่จะพูดว่า " อย่าเขียนโค้ดทำอะไรเขียนว่าทำไมโค้ดถึงทำในสิ่งที่มันทำ "

// 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, "");

ถ้าคุณไม่พยายามสอนใครบางคนเกี่ยวกับ regexes ผ่านความคิดเห็นในรหัสฉันไม่คิดว่าจะอธิบายสิ่งที่แต่ละชิ้นจะทำ เมื่อทำงานร่วมกับโปรแกรมเมอร์คนอื่น ๆ คุณสามารถสันนิษฐานได้ว่าใคร ๆ จะรู้ว่าอะไรเป็นนิพจน์ทั่วไปทั่วโลก


3
คุณจะประหลาดใจ ...
แมตต์

6

ฉันเดาว่ามันขึ้นอยู่กับว่าคุณรวม regex เข้าด้วยกันอย่างไร โดยทั่วไปฉันคิดว่าเป็นความคิดที่ดีที่จะใส่ความคิดเห็นไว้ในสตริง regex จริง ๆ (ไม่สามารถทำได้ในสถานการณ์ส่วนใหญ่เท่าที่ฉันรู้) หากคุณต้องการแสดงความคิดเห็นเฉพาะบางส่วนของนิพจน์ทั่วไป (คุณพยายามสอนใครบางคนหรือไม่) จากนั้นแบ่งแต่ละอันออกเป็นสตริงแยกกันในบรรทัดของตนเองและแสดงความคิดเห็นแต่ละบรรทัดโดยใช้กระบวนการแสดงความคิดเห็นปกติสำหรับภาษาโปรแกรมของคุณ มิฉะนั้นคำตอบของ pleinolijf ก็ค่อนข้างดี

ตัวอย่าง:

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

4

ฉันมักจะกำหนดค่าคงที่สตริงที่ชื่ออธิบายถึงวัตถุประสงค์โดยรวมของการแสดงออกปกติ

ตัวอย่างเช่น:

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

คุณสามารถเพิ่มความคิดเห็นข้างบนค่าคงที่นี้เพื่อให้คำอธิบาย แต่โดยปกติชื่อค่าคงที่ควรจะเพียงพอ


1
สิ่งที่พิเศษหนึ่งที่ผมชอบเกี่ยวกับคำตอบนี้ก็คือว่าหากได้รับใช้ในกว่าจุดหนึ่งความตั้งใจที่มีจะได้รับการดำเนินการประมาณเกินไป - ไม่ลืมที่จะแสดงความคิดเห็นมัน
J Trana

3

ในบางสถานการณ์ผู้พัฒนาอาจใช้นิพจน์ทั่วไปเพื่อจับคู่ข้อความนอกโดเมนทั่วไป นักพัฒนาดั้งเดิมอาจต้องผ่านการทำซ้ำหลายครั้งในการจับเคสขอบต่างๆที่อาจถูกค้นพบผ่านกระบวนการวนซ้ำนั้นเท่านั้น ดังนั้นผู้พัฒนาที่ตามมาอาจไม่ได้ตระหนักถึงกรณีขอบจำนวนมากที่นักพัฒนาดั้งเดิมจัดการกับแม้ว่าพวกเขาจะตระหนักถึงกรณีทั่วไป

ในกรณีเช่นนี้อาจเป็นประโยชน์กับเอกสารตัวอย่างของรูปแบบที่เปลี่ยนแปลง ตำแหน่งของเอกสารนี้อาจแตกต่างกันไปขึ้นอยู่กับจำนวนเงิน (เช่นไม่จำเป็นในรหัส)

วิธีหนึ่งในการเข้าถึงคือสมมติว่าผู้พัฒนาในอนาคตจะมีความรู้พื้นฐานเช่นการแสดงออกปกติ แต่ไม่มีความรู้ใด ๆ ที่คุณ (1) เคยมีมาก่อนการพัฒนานิพจน์ทั่วไปที่ไม่จำเป็นต้องรู้จัก นักพัฒนาในอนาคตหรือ (2) ความรู้ที่คุณได้รับระหว่างการพัฒนา (เช่นกรณีที่มีการค้นพบ)

ตัวอย่างเช่นหากในระหว่างการพัฒนาคุณพูดว่า "โอ้ฉันไม่รู้ว่า X สามารถใช้แบบฟอร์มนี้" ดังนั้นจึงควรบันทึกไว้ว่า (และอาจเป็นส่วนหนึ่งของ regex ที่จัดการรูปแบบนั้น)


2

ความคิดเห็นควรเพิ่มข้อมูลที่เป็นประโยชน์ที่ไม่ชัดเจนจากรหัส

  1. ทำให้ง่ายต่อการเข้าใจว่านิพจน์ควรทำอะไรที่ระดับความต้องการทั้งในโค้ดเองหรือในความคิดเห็น เจตนาในการแสดงออกคืออะไรเพื่อตรวจสอบที่อยู่อีเมลหรือเลือกหมายเลขโทรศัพท์แคนาดา
  2. ทำให้ง่ายต่อการเข้าใจว่านิพจน์กำลังทำอะไรจริง ๆ นั่นคือสิ่งที่นิพจน์ประเมิน ก่อนอื่นให้พยายามทำให้ชัดเจนโดยแยกนิพจน์ถ้าคุณตรวจสอบเครื่องหมายยัติภังค์ทั้งหมดแล้วเอาตัวเลขทั้งหมดออกแล้วทำให้นิพจน์สองส่วนที่มีตัวแปรที่เก็บค่าตัวกลางนั้นจะทำให้อ่านง่ายขึ้นและผู้อ่านจะอ่านมากขึ้น สามารถก้าวผ่านตรรกะของคุณทีละขั้นตอน (มีคำตอบสำหรับคำถามเกี่ยวกับ SE ที่ใครบางคนกำลังพยายามถอดรหัสรหัสเก่าซึ่งเกี่ยวข้องกับการจัดการบิต '>>' และค้นหาว่ามีการตั้งค่าสถานะบางอย่างที่คำตอบไม่เพียง แต่รหัสจริง แต่อย่างไร คำถามของผู้เขียนควรไปเกี่ยวกับการแยกแยะรหัสในอนาคตซึ่งเป็นสิ่งที่ฉันพยายามจะอธิบาย แต่ฉันก็สามารถทำได้

มีแอปพลิเคชั่นไม่กี่ตัวที่ต้องใช้ทุกรอบสุดท้ายหากคุณจับคู่รูปแบบชุดข้อมูลขนาดใหญ่อาจมีวิธีที่ดีกว่าอาจจะไม่ใช่ แต่สำหรับทุกสิ่งส่วนใหญ่เวลาดำเนินการพิเศษนั้นไม่ใช่เรื่องใหญ่

และจำคนต่อไปที่จะเจอรหัสของคุณและแก้ไขข้อผิดพลาดอาจเป็นคุณในเวลาหกเดือนและไม่มีทางที่คุณจะจำสิ่งที่มันควรจะทำ


1

แยก RegEx ลงในคลาสที่แยกออกมาเป็น a ด้วยชื่อที่มีความหมาย จากนั้นฉันจะบันทึกรหัสด้วยการทดสอบอัตโนมัติ

สิ่งนี้จะทำให้มั่นใจ

  • รหัสนั้นใช้ได้จริง - สำหรับกรณีมุม
  • ตรวจสอบให้แน่ใจว่า "การแก้ไขข้อบกพร่อง" อย่างรวดเร็วไม่ทำให้มุมตัวพิมพ์ใหญ่เกินไป
  • อาจปรับเอกสารให้เหมาะสมเมื่อปิดการใช้งานการย้อนรอย

โดยปกติคลาสของคุณอาจโฮสต์หลาย regex

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.