Apakah lookaround mungkin dalam sistem regex vim?

22

Saya telah menemukan banyak situasi di vim di mana akan berguna untuk memiliki pernyataan lookaround. Saya telah mencoba menggunakan sintaks lookaround standar ( (?=), (?!)dll.) , Tetapi tampaknya vim tidak mendukung ini. Apakah vim memiliki sintaks yang setara untuk pernyataan seperti ini?

Pohon cemara
sumber

Jawaban:

29

Jangkar "Zoom"

Selain jawaban @ jecxjo, ada banyak situasi di mana Anda dapat menggunakan jangkar nol-lebar \zsdan \zebukannya mencari-cari yang positif. Jangkar-jangkar ini menentukan awal ( \zs) dan akhir ( \ze) dari pertandingan dalam pola penuh.

Contohnya

  • foo\zsbarakan cocok bardidahului oleh foo( foobukan bagian dari pertandingan)
  • foo\zebarakan cocok foodiikuti oleh bar( barbukan bagian dari pertandingan)
  • myFunction(\zs.*\ze)akan cocok dengan parameter dalam panggilan fungsi (untuk tujuan demonstrasi, saya tidak fokus pada pencocokan serakah vs tidak serakah)

Menggunakannya

Ini menjadi sangat berguna saat menggunakan :substituteperintah. Misalnya, saya ingin mengganti parameter dalam pemanggilan fungsi myFunction()dengan foo:

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

Ini akan pergi myFunction(dan )utuh, dan Anda tidak perlu khawatir tentang menangkap mereka dalam pola Anda atau mengulanginya di pengganti Anda .

Anda bisa melakukan ini menggunakan fitur lookaround dari regex Vim, tetapi cukup kikuk:

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

(Saya menemukan sintaksis ini menyebabkan saya melupakan apa yang saya coba lakukan sejak awal.)

Anda masih perlu mencari-cari kadang-kadang

Masih ada situasi di mana Anda perlu mencari. Menggunakan \zsdan \zebagus untuk situasi sederhana di mana Anda memiliki sesuatu sebelum diikuti oleh teks untuk mencocokkan diikuti oleh sesuatu setelah . Tetapi jika itu lebih kompleks dari itu, Anda mungkin harus tetap menggunakan sintaks lookaround yang lebih berat.

Fakta yang menyenangkan

Meskipun mereka jauh lebih jelek, lookaround Vim lebih kuat daripada yang ada di PCRE! Mereka mendukung tampilan negatif panjang variabel, yang berarti Anda dapat menegaskan bahwa beberapa pola yang panjangnya tidak ditentukan tidak sebelum pertandingan Anda.

PCRE tidak mendukung ini, karena ini cukup mahal secara komputasi. Itu bukan masalah besar di Vim, karena kasus penggunaan paling umum dari regex cenderung melibatkan pencarian interaktif di mana waktu perhitungannya hampir tak terlihat oleh pengguna. Anda mungkin akan memperhatikannya jika digunakan untuk penyorotan sintaks.

Topik Bantuan yang Relevan

  • :help \zs
  • :help \ze
  • :help perl-patterns
tommcdo
sumber
Saya tidak mengetahui adanya jangkar zoom. Terima kasih telah menjelaskannya.
EvergreenTree
14

Sepertinya ini mungkin. Ada tabel sederhana untuk beralih dari perl ke vim.: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)

Jadi misalnya jika Anda memiliki string one two threedan Anda ingin mencocokkan onehanya jika <space>twomengikutinya Anda dapat menggunakan

/one\(\stwo\)\@=

Ini mirip dengan versi perl

m/one(?=\stwo)/
jecxjo
sumber