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 matchpatternpattern\@!— negative lookahead: what follows must not matchpatternpattern\@<=— positive lookbehind: what precedes must matchpatternpattern\@<!— negative lookbehind: what precedes must not matchpattern
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\)\@!matchesfoothat is preceded bybarand not followed bybaz - Test patterns interactively with
:set hlsearchand type in the search prompt to see matches highlight in real time