Là có thể nhìn trong hệ thống regex của vim?


22

Tôi đã gặp nhiều tình huống trong vim, nơi nó sẽ hữu ích để có những tuyên bố nhìn. Tôi đã thử sử dụng cú pháp tìm kiếm tiêu chuẩn ( (?=), (?!)v.v.) , nhưng có vẻ như vim không hỗ trợ điều này. Vim có một cú pháp tương đương cho các loại câu lệnh này không?

Câu trả lời:


29

Neo "Zoom"

Ngoài câu trả lời của @ jecxjo, có nhiều tình huống bạn có thể sử dụng các neo có độ rộng bằng không \zs\zethay vì nhìn tích cực. Các neo này xác định start ( \zs) và end ( \ze) của trận đấu trong mẫu đầy đủ.

Ví dụ

  • foo\zsbarsẽ khớp bartrước foo( fookhông phải là một phần của trận đấu)
  • foo\zebarsẽ khớp footheo sau bar( barkhông phải là một phần của trận đấu)
  • myFunction(\zs.*\ze)sẽ khớp với các tham số trong lệnh gọi hàm (cho mục đích trình diễn, tôi không tập trung vào kết hợp tham lam và không tham lam)

Đưa nó vào sử dụng

Chúng trở nên hữu ích nhất khi sử dụng :substitutelệnh. Ví dụ: giả sử tôi muốn thay thế các tham số trong lệnh gọi hàm myFunction()bằng foo:

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

Điều này sẽ để lại myFunction()nguyên vẹn, và bạn không phải lo lắng về việc bắt chúng trong mẫu của bạn hoặc lặp lại chúng trong thay thế của bạn .

Bạn có thể làm điều này bằng cách sử dụng tính năng nhìn của regim của Vim, nhưng nó khá là rắc rối:

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

(Tôi thấy cú pháp này khiến tôi quên đi những gì tôi đã cố gắng làm ở nơi đầu tiên.)

Thỉnh thoảng bạn vẫn cần nhìn

Vẫn có những tình huống mà bạn cần nhìn. Sử dụng \zs\zerất tốt cho các tình huống đơn giản trong đó bạn có một cái gì đó trước khi tiếp theo bằng văn bản để phù hợp với sau đó là một cái gì đó sau . Nhưng nếu nó phức tạp hơn thế, có lẽ bạn sẽ phải tuân theo cú pháp nhìn nặng hơn.

Sự thật thú vị

Mặc dù chúng xấu hơn đáng kể, nhưng vẻ ngoài của Vim mạnh hơn so với PCRE! Chúng hỗ trợ giao diện tiêu cực có độ dài thay đổi, nghĩa là bạn có thể khẳng định rằng một số mẫu có độ dài không được xác định trước không nằm trước trận đấu của bạn.

PCRE không hỗ trợ điều này, vì nó khá tốn kém về mặt tính toán. Đó không phải là mối quan tâm lớn ở Vim, vì các trường hợp sử dụng phổ biến nhất của regex có xu hướng liên quan đến tìm kiếm tương tác trong đó thời gian tính toán gần như không thể chấp nhận được đối với người dùng. Bạn có thể nhận thấy nó nếu nó được sử dụng để làm nổi bật cú pháp, mặc dù.

Chủ đề trợ giúp có liên quan

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

Tôi đã không nhận thức được các neo phóng to. Cảm ơn đã giải thích chúng.
EvergreenTree

14

Có vẻ như điều này là có thể. Có một bảng đơn giản để đi từ perl đến 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)

Vì vậy, ví dụ nếu bạn có chuỗi one two threevà bạn chỉ muốn khớp với onenếu <space>twotheo sau nó, bạn có thể sử dụng

/one\(\stwo\)\@=

Điều này tương tự như phiên bản perl

m/one(?=\stwo)/
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.