vimの正規表現システムでルックアラウンドは可能ですか?


22

ルックアラウンドステートメントがあると便利なvimの多くの状況に遭遇しました。私は、標準の前後参照の構文を使用して試してみました(?=)(?!)等。)が、Vimがこの機能をサポートしていません表示されます。vimには、これらの種類のステートメントと同等の構文がありますか?

回答:


29

「ズーム」アンカー

@jecxjoの答えに加えて、積極的なルックアラウンドの代わりにゼロ幅アンカー\zsを使用できる状況が多くあります\ze。これらのアンカーは、完全なパターン内の一致の開始(\zs)および終了(\ze)を定義します。

  • foo\zsbar一致するbarが先行するfoofoo一致の一部ではありません)
  • foo\zebarfoo後に続くbar(一致のbar一部ではない)
  • myFunction(\zs.*\ze)関数呼び出しのパラメーターと一致します(デモ目的のために、欲張りマッチングと非欲張りマッチングに焦点を合わせていません)

使用する

これらは、:substituteコマンドを使用するときに最も役立ちます。たとえば、私は、関数呼び出しのパラメータを交換したかったと言うmyFunction()foo

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

これはそのままmyFunction()そのまま残り、パターンでキャプチャしたり、置換でそれらを繰り返すことを心配する必要はありません。

Vimの正規表現のルックアラウンド機能を使用してこれを行うことができますが、非常に不格好です:

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

(この構文は、最初にやろうとしていたことを忘れさせてしまうことに気づきます。)

あなたはまだ時々見回す必要があります

まだ見回す必要がある状況があります。を使用する\zsと、テキストが続き、に一致するテキストが続く\ze単純な状況に最適です。しかし、それよりも複雑な場合は、おそらくより重いルックアラウンド構文に従う必要があります。

楽しい事実

それらはかなりいですが、VimのルックアラウンドはPCREのルックアラウンドよりも強力です!これらは、可変長の負の後読みをサポートしています。つまり、長さが事前に決められてないパターンは、一致する前ではないと断言できます。

PCREは、計算コストがかなり高いため、これをサポートしていません。正規表現の最も一般的なユースケースでは、計算時間がユーザーにほとんど知覚されないインタラクティブな検索が含まれる傾向があるため、これはVimの大きな関心事ではありません。ただし、構文の強調表示に使用されている場合は、おそらく気付くでしょう。

関連するヘルプトピック

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

ズームアンカーについては知りませんでした。それらを説明してくれてありがとう。
エバーグリーン

14

これが可能であるかのように見えます。perlから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)

たとえば、文字列がone two threeあり、それに続くone場合にのみ一致させたい<space>two場合は、使用できます

/one\(\stwo\)\@=

これはperlバージョンに似ています

m/one(?=\stwo)/
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.