vimtricks.wiki Concise Vim tricks, one at a time.

How do I match a pattern only when followed or preceded by another pattern in Vim?

Answer

\@= and \@! and \@<= and \@<!

Explanation

Vim's regex engine supports zero-width lookahead and lookbehind assertions using the \@=, \@!, \@<=, and \@<! atoms. These let you match text only when it is followed by, not followed by, preceded by, or not preceded by another pattern — without including that surrounding text in the match.

How it works

The assertion atom always appears after the sub-pattern it describes:

  • pattern\@= — positive lookahead: what follows must match pattern
  • pattern\@! — negative lookahead: what follows must not match pattern
  • pattern\@<= — positive lookbehind: what precedes must match pattern
  • pattern\@<! — negative lookbehind: what precedes must not match pattern

All four assertions are zero-width — they do not consume characters in the match.

Example

Find foo only when not followed by bar:

/foo\(bar\)\@!

Find the word return only when preceded by a space (not at start of line):

/ \@<=return

Extract just the value after = in key=value without matching = itself:

/=\@<=\w\+

Tips

  • Use \v (very magic) mode to reduce backslashes: /\v(bar)@!foo
  • Lookbehind in Vim must be fixed-width — variable-length lookbehinds are not supported
  • The assertions compose: /foo\(bar\)\@<=\(baz\)\@! matches foo that is preceded by bar and not followed by baz
  • Test patterns interactively with :set hlsearch and type in the search prompt to see matches highlight in real time

Next

How do I match a pattern only when it is preceded or followed by another pattern, without including that context in the match?