เป็นไปได้ที่การค้นหาในระบบ regex ของกลุ่ม?


22

ฉันได้พบกับสถานการณ์หลายอย่างในกลุ่มที่มันจะมีประโยชน์ที่จะมีงบ lookaround ฉันได้พยายามใช้ LookAround ไวยากรณ์มาตรฐาน( (?=), (?!)ฯลฯ .. )แต่ปรากฏว่าเป็นกลุ่มไม่สนับสนุนเรื่องนี้ เป็นกลุ่มมีไวยากรณ์ที่เทียบเท่าสำหรับคำสั่งประเภทนี้?

คำตอบ:


29

จุดยึด "ซูม"

นอกเหนือจากคำตอบของ @ jecxjo ยังมีอีกหลายสถานการณ์ที่คุณสามารถใช้จุดยึดความกว้างเป็นศูนย์\zsและ\zeแทนที่จะมองเชิงบวก จุดยึดเหล่านี้จะกำหนดจุดเริ่มต้น ( \zs) และจุดสิ้นสุด ( \ze) ของการจับคู่ภายในรูปแบบเต็ม

ตัวอย่าง

  • foo\zsbarจะจับคู่barนำหน้าด้วยfoo( fooไม่ใช่ส่วนหนึ่งของการแข่งขัน)
  • foo\zebarจะจับคู่fooตามด้วยbar( barไม่ใช่ส่วนหนึ่งของการแข่งขัน)
  • myFunction(\zs.*\ze)จะจับคู่พารามิเตอร์ในการเรียกใช้ฟังก์ชัน(เพื่อวัตถุประสงค์ในการสาธิตฉันไม่ได้มุ่งเน้นไปที่การจับคู่โลภและการจับคู่ที่ไม่ใช่โลภ)

นำไปใช้งาน

สิ่งเหล่านี้มีประโยชน์มากที่สุดเมื่อใช้:substituteคำสั่ง ตัวอย่างเช่นฉันต้องการแทนที่พารามิเตอร์ในการเรียกใช้ฟังก์ชันmyFunction()ด้วยfoo:

:%s/myFunction(\zs.*\ze)/foo/

นี้จะทำให้myFunction(และ)เหมือนเดิมและคุณไม่ต้องกังวลเกี่ยวกับการจับภาพไว้ในคุณรูปแบบหรือทำซ้ำในคุณทดแทน

คุณสามารถทำได้โดยใช้คุณสมบัติ lookaround ของ regim ของ Vim แต่มันค่อนข้างเป็นเรื่องที่ไม่แน่นอน:

:%s/\(myFunction(\)\@<=.*\()\)\@=/foo/

(ฉันพบว่ารูปแบบนี้ทำให้ฉันลืมสิ่งที่ฉันพยายามทำตั้งแต่แรก)

คุณยังต้องมีการตรวจสอบบางครั้ง

ยังมีสถานการณ์ที่คุณต้องมีการตรวจสอบ การใช้\zsและ\zeเป็นที่ดีสำหรับสถานการณ์ง่ายๆที่คุณมีบางสิ่งบางอย่างก่อนที่จะตามด้วยข้อความให้ตรงกับตามด้วยบางสิ่งบางอย่างหลังจากที่ แต่ถ้ามันซับซ้อนกว่านั้นคุณอาจต้องยึดติดกับรูปลักษณ์ที่หนักกว่า

สนุกกับความเป็นจริง

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

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

หัวข้อความช่วยเหลือที่เกี่ยวข้อง

  • :help \zs
  • :help \ze
  • :help perl-patterns

ฉันไม่ทราบถึงจุดยึดการซูม ขอบคุณที่อธิบายพวกเขา
EvergreenTree

14

ดูเหมือนว่าเป็นไปได้ มีตารางง่าย ๆ ที่จะไปจาก Perl ไปเป็นกลุ่ม:h perl-patterns

9. Compare with Perl patterns               *perl-patterns*

Vim's regexes are most similar to Perl's, in terms of what you can do.  The
difference between them is mostly just notation;  here's a summary of where
they differ:

Capability                  in Vimspeak   in Perlspeak
----------------------------------------------------------------
force case insensitivity    \c            (?i)
force case sensitivity      \C            (?-i)
backref-less grouping       \%(atom\)     (?:atom)
conservative quantifiers    \{-n,m}       *?, +?, ??, {}?
0-width match               atom\@=       (?=atom)
0-width non-match           atom\@!       (?!atom)
0-width preceding match     atom\@<=      (?<=atom)
0-width preceding non-match atom\@<!      (?<!atom)
match without retry         atom\@>       (?>atom)

ตัวอย่างเช่นหากคุณมีสตริงone two threeและคุณต้องการจับคู่oneเฉพาะเมื่อ<space>twoติดตามคุณสามารถใช้

/one\(\stwo\)\@=

นี้คล้ายกับรุ่น perl

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