回答:
@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(
で)
そのまま残り、パターンでキャプチャしたり、置換でそれらを繰り返すことを心配する必要はありません。
Vimの正規表現のルックアラウンド機能を使用してこれを行うことができますが、非常に不格好です:
:%s/\(myFunction(\)\@<=.*\()\)\@=/foo/
(この構文は、最初にやろうとしていたことを忘れさせてしまうことに気づきます。)
まだ見回す必要がある状況があります。を使用する\zs
と、前にテキストが続き、後に一致するテキストが続く\ze
単純な状況に最適です。しかし、それよりも複雑な場合は、おそらくより重いルックアラウンド構文に従う必要があります。
それらはかなりいですが、VimのルックアラウンドはPCREのルックアラウンドよりも強力です!これらは、可変長の負の後読みをサポートしています。つまり、長さが事前に決められていないパターンは、一致する前ではないと断言できます。
PCREは、計算コストがかなり高いため、これをサポートしていません。正規表現の最も一般的なユースケースでは、計算時間がユーザーにほとんど知覚されないインタラクティブな検索が含まれる傾向があるため、これはVimの大きな関心事ではありません。ただし、構文の強調表示に使用されている場合は、おそらく気付くでしょう。
:help \zs
:help \ze
:help perl-patterns
これが可能であるかのように見えます。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)/