การแสดงออกปกติไม่ได้


36

ถามคนที่มีพื้นฐานด้านวิทยาศาสตร์คอมพิวเตอร์ว่านิพจน์ปกติคืออะไรและคำตอบน่าจะเกินกว่าข้อ จำกัด ของการเข้าถึงออโตเมติก จำกัด ของรัฐ

ตัวอย่างเช่น“ นิพจน์ทั่วไป”

/^1?$|^(11+?)\1+$/

ที่สร้างขึ้นโดยบุคลิกภาพ Perl ตั้งข้อสังเกตAbigail (และเป็นส่วนหนึ่งของชุดทดสอบของ Perlตั้งแต่ปี 2002) อธิบายเครื่องที่ยอมรับตัวเลขเอกเพียงคอมโพสิต แต่การออกกำลังกาย 4.5 (ข)ในรุ่นที่สามของปีเตอร์ลินซ์ของแนะนำอย่างเป็นทางการภาษาและออโตมีการใช้ผู้อ่านแทรกสูบน้ำที่จะพิสูจน์ว่า

L={an:n is not a prime number}

ไม่ใช่ภาษาปกติ

ในบริบทที่ความแตกต่างสำคัญเราควรเรียกการแสดงออกที่ทรงพลังกว่านี้อย่างเคร่งครัดว่าอย่างไร

คำตอบ:


46

Larry Wall เสนอว่าเราใช้ "expression ปกติ" สำหรับ Kleene ที่เป็นทางการซึ่งเสนอและ "regex" สำหรับนิพจน์สำหรับส่วนขยายที่ใช้กันอย่างแพร่หลาย มันค่อนข้างเป็นไปตามอนุสัญญาอย่างกว้างขวาง หากคุณต้องการให้ชัดเจนว่าคุณกำลังพูดถึงการแสดงออกปกติในความหมายของภาษาที่เป็นทางการก็มักจะไม่ยากที่จะแปลเป็นการพูดคุยของภาษาปกติ

พลังของ regexes มาจากการย้อนรอยและมีการทำออโตมาตะสำหรับภาษาปกติที่มีการย้อนรอย ดูโดยเฉพาะอย่างยิ่ง Becchi & ลี่ย์ปี 2008 ขยาย Finite Automata เพื่อนิพจน์ปกติอย่างมีประสิทธิภาพตรงกับ


5
ฉันเห็นด้วยบางอย่างเช่น "Perl regex" ("POSIX regex" ฯลฯ ) กับ "ภาษาปกติ" ควรมีความชัดเจนเพียงพอที่จะป้องกันการตีความผิด ๆ
Jukka Suomela

Perl regexes มีคุณสมบัติเพิ่มเติมมากมายมากกว่าเพียงแค่การย้อนรอย
reinierpost

@reierierpost จริง แต่ฉันคิดว่าการย้อนรอยเป็นสิ่งที่สำคัญที่สุดในมุมมองของภาษาที่เป็นทางการ Perl regexes มีคุณสมบัติเช่นการรันโค้ด Perl ตามอำเภอใจ แต่ฉันคิดว่า regexes ควรตีความอย่างหลวม ๆ เหมือนกับครอบคลุม PCREs PCREs มีสิ่งแปลกประหลาดเช่นรูปแบบซ้ำซาก แต่เป็นศาสตร์มืดนำคุณออกไปนอกขอบเขตของภาษาปกติ ฉันสามารถอัปเดตคำตอบของฉันเพื่อให้ครอบคลุมถึงสิ่งเหล่านี้
Charles Stewart

18

สำนวนเหล่านี้ได้รับการตรวจสอบโดย Aho (คู่มือวิทยาศาสตร์คอมพิวเตอร์เชิงทฤษฎี, Vol. A, Chp. 5) และ Campeanu, Salomaa, Yu ("การศึกษาอย่างเป็นทางการของนิพจน์ทั่วไปที่ใช้งานได้จริง", วารสารฐานรากสากลของวิทยาศาสตร์คอมพิวเตอร์, 14: 1007 –1018, 2003) รวมถึงเอกสารติดตามผลบางส่วน

Aho เรียกการแสดงออกที่มีประสิทธิภาพมากขึ้น "rewbr" (นิพจน์ทั่วไปที่มีการอ้างอิงย้อนกลับ), Campeanu et al ใช้ "การแสดงออกปกติขยาย" เช่นเดียวกับ "การแสดงออกปกติปฏิบัติ" ดูเหมือนว่า "การแสดงออกปกติเพิ่มเติม" เป็นคำที่ใช้บ่อยที่สุดในวรรณคดีล่าสุด

การสร้างคำว่า "การแสดงออกทางเหตุผล" จากโรงเรียนฝรั่งเศสและจากการพิจารณาข้อเท็จจริงที่ว่าการแสดงออกเหล่านั้นถูกนำมาใช้ในโลกแห่งความจริงฉันเองก็ชอบ "การแสดงออกที่แท้จริง"

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

อันดับแรกregexและrewbrไม่ได้ม้วนลิ้นจริงๆและใช้พวกเขาซ้ำแล้วซ้ำอีกในหลักสูตรของกระดาษทั้งหมดได้น่าเบื่อจริงๆในการเขียนและอ่านโดยเฉพาะอย่างยิ่งเมื่อใช้รูปแบบพหูพจน์ใด ๆ ที่เป็นไปได้ การแสดงออกปกติเหมือน PERLก็ค่อนข้างเทอะทะ แน่นอนว่าฉันไม่ใช่เจ้าของภาษาดังนั้น YMMV

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

ประการที่สามผมอยากจะใช้คำที่ถูกใช้ไปแล้วในวรรณคดีมาตลอดระยะเวลาประกาศเกียรติคุณใหม่ซึ่งทิ้งฉันเลือกระหว่างการแสดงออกปกติขยายและการแสดงออกปกติในทางปฏิบัติ ตัวเลือกที่สองบอกเป็นนัย (อย่างน้อยโดยปริยาย) ว่าการแสดงออกปกติที่เหมาะสมนั้นไม่สามารถทำได้ซึ่งรู้สึกค่อนข้างแปลก (โดยเฉพาะอย่างยิ่งเมื่อ RE2 ของ Google ไม่ได้ใช้ backrefs และดูเหมือนจะใช้งานได้จริง)

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


7
น่าเสียดายที่คำว่านิพจน์ทั่วไปที่ขยายเพิ่มนั้นมีอยู่แล้วโดย POSIX ซึ่งแยกความแตกต่างระหว่างนิพจน์ทั่วไปพื้นฐาน (BRE)และนิพจน์ทั่วไปที่ขยายเพิ่ม (ERE)ซึ่งทั้งคู่เป็นนิพจน์ปกติที่ขยายตามคำจำกัดความของคุณ
Jörg W Mittag

@ Jörg: ตามจริงแล้วสิ่งนี้ไม่ได้แสดงออกปกติ POSIX แบบขยายหรือพื้นฐานมีประสิทธิภาพมากกว่าการแสดงออกปกติ และ BRE ที่แท้จริง (ไม่ใช่ GNU) ดูเหมือนจะมีประสิทธิภาพน้อยกว่านิพจน์ทั่วไป (ไม่มีโอเปอเรเตอร์สำรอง)
sepp2k

ดูที่ "การขยายการแสดงออกปกติ" โดย Carle และ Narendran (2009) สำหรับผลลัพธ์ล่าสุดเกี่ยวกับ "rewbr" นี้: portal.acm.org/citation.cfm?id=1533235
Jakob

ผลการศึกษาล่าสุดของชั้นเรียนภาษานี้เพิ่มเติม: "ที่จุดตัดของภาษา regex กับภาษาปกติ" โดย Campeanu และ Santean (TCS 410, 2009) "การทดสอบการจับคู่พหุนามเวลาสำหรับคลาสขนาดใหญ่ของการแสดงออกปกติเพิ่มเติม" โดย Reidenbach และ Schmid (CIAA 2010 ) และ "นิพจน์ทั่วไปแบบขยาย: ความกะทัดรัดและ Decidability" (โดยฉันเนื่องจากปรากฏใน STACS 2011)
Dominik D. Freydenberger

6

มันเป็นที่รู้จักกันว่าสิ่งที่เรียกว่า regexp ของ perl นั้นทรงพลังพอที่จะทำให้ทัวริงสมบูรณ์ มีแม้กระทั่งคอมไพเลอร์จากโปรแกรมปกติถึง Perl regexp

ดังนั้นฉันสงสัยว่ามันสมเหตุสมผลแล้วที่จะค้นหาชื่อสำหรับ "regexps" แบบนี้

ดูตัวอย่างได้ที่http://search.cpan.org/~asavige/Acme-EyeDrops-1.62/lib/Acme/EyeDrops.pm


คุณมีพอยน์เตอร์บ้างไหม?
András Salamon

5
@ András: ฉันคิดว่า Arthur กำลังพูดถึง?{CODE}คำสั่งของ Perl ที่อนุญาตให้นิพจน์รูปแบบสอดแทรกโค้ดโปรแกรมในนิพจน์ทั่วไป ฉันเข้าใจว่า PCRE นั้นมีการกำหนดโดยทั่วไปว่าเป็นส่วน "ที่เปิดเผย" ของภาษาทั้งภาษาที่ถูกเรียกว่ารูปแบบภาษา อ้างอิงจาก WP, Aho, 1990, "อัลกอริทึมสำหรับการค้นหารูปแบบในสตริง" แสดงให้เห็นว่าปัญหาความเป็นสมาชิกสำหรับภาษาปกติท ไม่มีคุณสมบัติที่ยากอื่น ๆ สำหรับ PCREs ที่ประกาศได้
Charles Stewart

ฉันเพิ่มลิงค์; ฉันไม่ได้ดูซอร์สโค้ดดังนั้นฉันจึงไม่รู้จริงๆว่ามันทำงานอย่างไรและหากมีข้อพิสูจน์ว่าการรวบรวมนั้นถูกต้องจริงๆ
Arthur MILCHIOR

1
ขออภัยตามอาร์กิวเมนต์ของคุณเนื่องจาก lambda-แคลคูลัสเป็นทัวริงสมบูรณ์จึงไม่สมเหตุสมผลที่จะค้นหาชื่อ เช่นเดียวกันกับการคำนวณและภาษาทัวริงที่สมบูรณ์อื่น ๆ ทั้งหมด จนถึงจุดนี้ทัวริงสมบูรณ์ไม่ได้อธิบายว่าภาษามีความหมายอย่างไรดังนั้นจึงไม่มีเหตุผลที่จะระบุภาษาเพียงเพราะพวกเขาเป็นภาษาทัวริงที่สมบูรณ์ ตัวอย่างของฉันเกี่ยวกับแลมบ์ดา - แคลคูลัสเป็นเรื่องสุดขั้วแน่นอน
Blaisorblade

2

ฉันคิดว่าคำที่ดีที่สุดสำหรับ "การแสดงออกปกติในบริบทของออโตมาตะ" คือ "การแสดงออกเชิงเหตุผล" ตามที่ใช้ในการพูดในองค์ประกอบของทฤษฎีออโตมาตะของ Sakarovitch หรือคู่มือของออตโตน้ำหนัก


1
ไม่นิยมใช้กันมาก IMHO
Blaisorblade

มัน / ถูก / ใช้กันอย่างแพร่หลายในทฤษฎีออโตถ่วงน้ำหนักดูen.wikipedia.org/wiki/Rational_language ฉันเคยเห็นมันเป็นช่วงเวลาที่ดีในด้านภาษามากกว่ากลุ่ม
Michaël Cadilhac

1

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

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


0

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


2
โดยหลักการแล้วฉันเห็นด้วยกับเหตุผลของคุณ แต่ Campeanu, Santean และ Yu ได้ใช้คำว่า " pattern pattern"เพื่อแสดงถึงคลาสที่คล้ายกันของภาษาที่มีคำจำกัดความที่ "สะอาด" (ดู "การแสดงออกของรูปแบบและ Automata pattern", IPL 92 (2004) ).
Dominik D. Freydenberger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.