เวทมนตร์ Regex ของ Vim เข้ากันได้กับคลาส Regex ที่รู้จักกันดีหรือไม่?


16

ไวยากรณ์นิพจน์ปกติของเครื่องมือ Unix จำนวนมากมักจะเป็น POSIX-codified Basic และ Extended Regular Expression (BRE และ ERE ตามลำดับ) และในการใช้งานที่ทันสมัยบางอย่างสไตล์ Perl (PCRE เป็นการนำไปใช้สิ่งนี้)

มีการโต้ตอบแบบหนึ่งต่อหนึ่งระหว่างระดับเวทมนตร์ของ Vim และคลาสที่มีการกำหนดจากภายนอก แต่เป็นที่รู้จักกันดี? ดูเหมือนว่า\mเป็น BRE และ\vเป็น ERE ยกเว้น POSIX ไม่รวมการค้นหา

หากมีการโต้ตอบดังกล่าวจะมีการกำหนดไว้ที่ไหน? มีเพียงหนึ่งเอ่ยถึงpattern.txtPOSIX

หรือเราต้องใช้ "เวทมนต์" เพื่ออธิบายการแสดงออกปกติของกลุ่ม?


3
ค่อนข้างแน่ใจว่า\vมี<>ขอบเขตของคำซึ่ง AFAIK นั้นไม่เหมือนใครใน Vim ดังนั้นไม่เพียงแค่อธิบายว่า "Vim regex" (ไม่โพสต์เป็นคำตอบเพราะฉันไม่ได้บวก)
Doorknob

@ Doorknob ฉันคิดว่าคุณอาจพบว่าการสนทนาของคำตอบตามความคิดเห็นที่น่าสนใจนี้ เนื่องจากความคิดเห็นของคุณมีผู้ลงคะแนนสามคนและไม่มีความคิดเห็นตอบเพื่อบอกคุณว่ามันไม่ถูกต้องอาจเป็นเรื่องที่ถูกต้อง (ฉันไม่แน่ใจ) แต่แนะนำให้แก้ไขและอื่น ๆ อัล เป็นไปไม่ได้ที่จะปรับปรุงความแม่นยำ ในฐานะที่เป็นคำตอบที่โพสต์ก็สามารถแก้ไขได้สำหรับความถูกต้องที่เพิ่มขึ้น, upvote, downvote, ตอบกลับและอื่น ๆ
Wildcard

คำตอบ:


22

โดยสรุปไม่มี Regex ของ Vim นั้นมีรสชาติที่เป็นเอกลักษณ์และไม่มีทางเลือกอื่นที่จะทำให้มันมีพฤติกรรมเหมือนกับรสชาติอื่น

ฉันคิดว่านี่เป็นสิ่งที่ดี

มายากล

'magic'ตัวเลือกที่จะไม่เปลี่ยนรสชาติของ regex ที่ใช้เป็นกลุ่ม มันสลับพฤติกรรมของ\อะตอมที่มีการหลีกเลี่ยงหลายอย่าง

ตัวอย่างเช่นโดยค่าเริ่มต้น+คือตัวอักษรตาม+ตัวอักษรโดยที่\+หมายถึง "อะตอมหนึ่งตัวหรือมากกว่า" ในทางตรงกันข้าม*หมายถึง "ศูนย์หรือมากกว่าของอะตอมก่อนหน้านี้" ในขณะที่เป็นตัวอักษร\* *หลายคนพบว่ามันค่อนข้างสับสน การใช้\vรูปแบบของคุณทำให้มันสอดคล้องกันมากขึ้น :help 'magic'ให้บทสรุปที่ดี:

after:    \v       \m       \M       \V         matches ~
                'magic' 'nomagic'
          $        $        $        \$         matches end-of-line
          .        .        \.       \.         matches any character
          *        *        \*       \*         any number of the previous atom
          ()       \(\)     \(\)     \(\)       grouping into an atom
          |        \|       \|       \|         separating alternatives
          \a       \a       \a       \a         alphabetic character
          \\       \\       \\       \\         literal backslash
          \.       \.       .        .          literal dot
          \{       {        {        {          literal '{'
          a        a        a        a          literal 'a'

ส่วนตัวผมคิดว่าการทำงานเริ่มต้นเป็นสิ่งที่ดีสำหรับไฟล์รหัสซึ่งก็ไม่ใช่เรื่องแปลกที่จะค้นหาสิ่งที่ต้องการโดยใช้อักษรfoo((

รสชาติ Regex ของ Vim

ฉันเคยเห็นหลายคนที่ต้องการให้ Vim รองรับ PCRE โดยส่วนตัวฉันต้องการเครื่องมืออื่น ๆ ที่สนับสนุนรสชาติของ regex ของ Vim มันมีความสามารถบางอย่างที่เป็นไปไม่ได้หรือยุ่งยากเกินไปที่จะประสบความสำเร็จใน PCRE

เป็นไปไม่ได้ใน PCRE

Lookaroundเป็นคุณสมบัติทั่วไปที่คุณสามารถยืนยันได้ว่ารูปแบบไม่ตรงกันหรือไม่ตรงกันก่อนหรือหลังรูปแบบที่คุณพยายามจับคู่ ตัวอย่างเช่นรูปแบบ PCRE q(?!u)(หรือเป็นกลุ่มรูปแบบ regex qu\@!) ตรงกับที่ไม่ได้ตามมาด้วยq u(สิ่งนี้ถูกต้องมากกว่าq[^u]ซึ่งต้องใช้ว่ามีอักขระบางตัวอยู่หลังq)

ลักษณะลบเชิงลบที่มีความยาวแปรผัน

PCRE และรสชาติอื่น ๆ มีข้อ จำกัด ว่ารูปแบบเชิงลบด้านหลังจะต้องมีความยาวคงที่ นั่นหมายความว่ารูปแบบเช่น(?<![a-z]{3})fooความหมาย "สตริงfoo ไม่นำหน้าด้วยตรง 3 ตัวอักษรตัวพิมพ์เล็ก") เป็นดี แต่(?<![a-z]+)foo(ความหมาย "สตริงfooไม่นำหน้าด้วยหมายเลขใด ๆของตัวอักษรตัวพิมพ์เล็ก") ไม่ได้

ข้อ จำกัด นี้ไม่มีอยู่ในกลุ่ม ใน Vim รูปแบบเช่น\([a-z]\+\)\@<!fooในขณะที่อาจดูน่าเกลียดเล็กน้อยก็ใช้ได้จริง

ง่ายกว่าใน Vim regex

บางสิ่งมีจำนวนมากขึ้นในรสชาติของ regex ของ Vim

จุดเริ่มต้นและจุดสิ้นสุดของจุดยึดที่ตรงกัน

สิ่งที่โดดเด่นที่สุดในความคิดของฉันคือ\zsและ\zeเบรก สิ่งเหล่านี้ช่วยให้คุณสามารถระบุจุดเริ่มต้นและจุดสิ้นสุดของการแข่งขัน ยกตัวอย่างเช่นfoo(\zs.*\ze)ที่ตรงกันเท่านั้นสิ่งที่อยู่ระหว่าง(และในการเรียกใช้ฟังก์ชันเช่น) foo(...)สิ่งนี้สามารถทำได้ใน PCRE แต่ต้องใช้ lookaround ซึ่งน่าเบื่อเล็กน้อย:(?<=foo\().*(?=\))

การจับคู่คำนำหน้า

อีกสิ่งที่ยอดเยี่ยมที่ Vim สามารถทำได้คือจับคู่คำนำหน้าใด ๆ (รวมถึงส่วนนำหน้าว่าง) ของลำดับอักขระเฉพาะ ตัวอย่างเช่นการจับคู่f, fo, fooหรือfoodรูปแบบf\%[ood]สามารถนำมาใช้ ใน PCRE, f(o(od?)?)?รูปแบบดังกล่าวจะมีลักษณะเหมือน (ลองจินตนาการดูว่าสตริงนั้นยาวกว่านี้!

การจับคู่ตำแหน่งเคอร์เซอร์บรรทัดและคอลัมน์

Regex ของ Vim มีจุดยึดสำหรับการจับคู่ตำแหน่งในบัฟเฟอร์


ฉันคิดว่ามันคุ้มค่าที่จะยอมรับรสชาติของ Regex ของ Vim มันเหมาะอย่างยิ่งสำหรับใช้ในโปรแกรมแก้ไขข้อความที่ใช้สำหรับการเขียนโปรแกรมเป็นหลัก

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