How do I match text only when it is followed by a specific pattern using zero-width lookahead?
Answer
\(pattern\)\@=
Explanation
Vim's regex engine supports zero-width positive lookahead via the \@= operator. The syntax is main_pattern\(lookahead\)\@=: place the lookahead pattern inside a group and append \@=. The search matches only when the main pattern is immediately followed by the lookahead — the lookahead itself is not consumed or included in the matched text, leaving the cursor at the end of main_pattern.
How it works
- Place the lookahead pattern in a captured group:
\(lookahead_pattern\) - Append
\@=to make the group match zero-width - Full form:
what_to_match\(what_must_follow\)\@=
\@= is the Vim equivalent of Perl's (?=pattern) positive lookahead.
Example
Given text:
print("hello")
println("world")
echo "hi"
Find print only when directly followed by (:
/print\(([)\@=
This matches print in print("hello") but not in println("world"), where print is followed by l, not (.
Tips
- Negative lookahead
\@!: match when NOT followed by a pattern — e.g.,foo\(bar\)\@!findsfoonot followed bybar - Positive lookbehind
\@<=: match when preceded by a pattern — e.g.,\(foo\)\@<=barfindsbaronly when preceded byfoo - Negative lookbehind
\@<!: match when NOT preceded by a pattern - Combine with
\zsand\zeto control which part of the match is highlighted or used in substitutions