ความแตกต่างระหว่าง '.' , '?' และ '*' ในนิพจน์ปกติ


21

ฉันจะได้รับตัวอย่างว่าองค์ประกอบสามอย่างนี้ (เรียกว่า metacharacters?) แตกต่างกันอย่างไร

ฉันรู้ว่านั่น*หมายถึงทั้งหมดหรือเปล่า แต่ฉันไม่แน่ใจว่ามันเป็นวิธีที่ถูกต้องในการคิดหรือไม่ ในทางกลับกัน.และ?ดูเหมือนกัน พวกมันตรงกับตัวละครตัวหนึ่งใช่มั้ย



@Cyrus หรือดียิ่งขึ้น: StackOverflow Regex เอกสาร
โทมัส Ayoub

คำตอบ:


16

นำมาจากWikipedia :

? เครื่องหมายคำถามระบุว่ามีศูนย์หรือองค์ประกอบหนึ่งรายการก่อนหน้า ตัวอย่างเช่น colou? r จับคู่ทั้ง "สี" และ "สี"

*เครื่องหมายดอกจันบ่งชี้ว่ามีการเกิดขึ้นขององค์ประกอบก่อนหน้าเป็นศูนย์หรือมากกว่านั้น ตัวอย่างเช่น ab * c ตรงกับ "ac", "abc", "abbc", "abbbc" และอื่น ๆ

ความแตกต่างที่สำคัญคือเครื่องหมายดอกจันจะจับคู่กับศูนย์หรือมากกว่านั้นในขณะที่เครื่องหมายคำถามตรงกับศูนย์หรือหนึ่งครั้ง เปรียบเทียบตัวอย่างทั้งสองนี้:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

เนื่องจากในcolouurตัวอักษร u (องค์ประกอบก่อนหน้าก่อนตัวระบุ?) เกิดขึ้นมากกว่าหนึ่งครั้งจึงไม่ตรงกับ?แต่จะจับคู่กับ*

ตัวอย่างที่คล้ายกัน:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

จากหน้าวิกิพีเดียเดียวกัน:

จับคู่อักขระเดี่ยวใด ๆ (แอปพลิเคชั่นจำนวนมากยกเว้นการขึ้นบรรทัดใหม่และตัวอักษรใดที่ถือว่าเป็นบรรทัดใหม่คือ - การเข้ารหัสอักขระ - และการระบุแพลตฟอร์มเฉพาะ ภายในนิพจน์วงเล็บเหลี่ยม POSIX อักขระจุดตรงกับจุดตัวอักษร ตัวอย่างเช่น ac ตรงกับ "abc" ฯลฯ แต่ [ac] จะจับคู่เฉพาะ "a", "." หรือ "c"

ในตัวอย่างของเรา

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

อย่างเหมาะสมพอคนสุดท้ายอ่านว่า match any line that has "colou", plus any character, plus letter "r"

ข้อสรุป

คุณถามว่า: "ฉันรู้ว่า '*' หมายถึงทั้งหมดหรือไม่ทำอะไรเลย แต่ฉันไม่แน่ใจว่ามันเป็นวิธีที่เหมาะสมที่จะคิดเกี่ยวกับมันในอีก ' & '?' ดูเหมือนกัน " อย่างที่คุณเห็นจุดและดอกจันนั้นไม่เหมือนกันทุกประการ จุดทำงานกับตัวละครใด ๆ ที่อาจครอบครองตำแหน่งนั้นในขณะที่เครื่องหมายคำถามทำงานกับองค์ประกอบก่อนหน้า


32

คุณอาจสับสนกับการแสดงออกปกติด้วยเปลือกที่โกลาหล

ในไวยากรณ์นิพจน์ทั่วไปแสดง.ถึงอักขระเดี่ยวใด ๆ (โดยปกติจะไม่รวมอักขระบรรทัดใหม่) ในขณะที่*ตัวบอกปริมาณหมายถึงศูนย์หรือ regex อะตอมก่อนหน้า (อักขระหรือกลุ่ม) ?เป็นตัวบอกปริมาณหมายถึงศูนย์หรือหนึ่งอินสแตนซ์ของอะตอมก่อนหน้าหรือ (ในตัวแปร regex ที่สนับสนุน) ตัวดัดแปลงที่ตั้งค่าพฤติกรรมของตัววัดปริมาณเป็นแบบไม่โลภ

ใน shell globs ?หมายถึงอักขระตัวเดียว (เช่น regex ของ.) ในขณะที่*หมายถึงลำดับของศูนย์หรือมากกว่าตัวละคร (เทียบเท่ากับ regex .*)

การอ้างอิงสองสามอย่างที่คุณอาจพบว่ามีประโยชน์คือhttp://www.regular-expressions.info/quickstart.htmlและhttp://mywiki.wooledge.org/glob


6

หมายเหตุ: Examples provided are in Python.แม้ว่าแนวคิดจะยังคงเหมือนเดิม

'.'เป็นสัญลักษณ์ที่ตรงกันซึ่งจับคู่กับอักขระใด ๆ ยกเว้นอักขระขึ้นบรรทัดใหม่ (ซึ่งสามารถแทนที่ด้วยre.DOTALLอาร์กิวเมนต์ใน Python ได้) ดังนั้นมันจะเรียกว่าเป็นสัญลักษณ์การค้นหา

'*'คือตัวระบุ (กำหนดความถี่ที่องค์ประกอบสามารถเกิดขึ้นได้) สั้นสำหรับ{0}

มันหมายถึง“ จับคู่กับศูนย์หรือมากกว่า” - กลุ่มที่นำหน้าดาวสามารถเกิดขึ้นได้หลายครั้งในข้อความ มันสามารถหายไปอย่างสมบูรณ์หรือซ้ำแล้วซ้ำอีก

'?'นอกจากนี้ยังมีปริมาณ สั้นสำหรับ{0,1}

หมายความว่า"จับคู่ศูนย์หรือหนึ่งในกลุ่มที่อยู่หน้าเครื่องหมายคำถามนี้" นอกจากนี้ยังสามารถตีความว่าเป็นส่วนหนึ่งก่อนหน้าเครื่องหมายคำถามเป็นตัวเลือก

เช่น:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

ในตัวอย่างข้างต้น '?' ระบุว่าตัวเลขสองหลักก่อนหน้าเป็นตัวเลือกพวกเขาอาจไม่เกิดขึ้นหรือเกิดขึ้นมากที่สุดครั้งเดียว

ความแตกต่างระหว่าง '.' และ '?':

'.'จับคู่ / ยอมรับ / ตรวจสอบอักขระเดี่ยวสำหรับสถานที่ที่ถืออยู่ในนิพจน์ทั่วไป

เช่น:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?'การแข่งขัน / สามารถตรวจสอบศูนย์หรือเกิดขึ้นเพียงครั้งเดียวของกลุ่มก่อนหน้านั้น

ตรวจสอบตัวอย่างหมายเลขโทรศัพท์มือถือ

'*'กันไปด้วย มันจะตรวจสอบเหตุการณ์ที่เกิดขึ้นเป็นศูนย์หรือมากกว่าของกลุ่มก่อนหน้านี้

รวม:

'.*': ยอมรับลำดับได้มากเท่าที่มีอยู่ วิธีโลภ

'.*?'ยอมรับลำดับและหยุดที่ตรงกันก่อน วิธีการไม่โลภ

สำหรับข้อมูลเพิ่มเติมลองอ่านคำถามสองข้อต่อไปนี้ ...

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