How do I search non-greedily across multiple lines between two markers?
/\vstart\_.{-}end
Multiline searches in Vim often overmatch because .
/\vstart\_.{-}end
Multiline searches in Vim often overmatch because .
/\vTODO:\s*\zs.{-}\ze\s*($|#)
When TODO comments include prefixes, owners, or trailing metadata, a plain search often lands on the wrong part of the line.
/foo\@<!bar
Vim regex supports zero-width assertions, so you can match text based on context without consuming the context itself.
/\%>20l\%<40lTODO
Vim's search engine can constrain matches by line number, which is useful when you want to scan a known section without touching the rest of the buffer.
:let @/ = '\V' . escape(expand('<cword>'), '\')
This pattern lets you prepare a precise search target without jumping the cursor or triggering an immediate search motion.
*Ndgn
When you are reviewing repetitive text, you often need to remove one specific match without running a broad substitute.
/pattern/e+1<CR>
Most Vim searches place the cursor at the start of the match.
/\%>10l\%<20lTODO
Vim regex supports position atoms that can constrain where a match is allowed to occur.
/\vfoo\zsbar\zebaz
When you need to target only a slice of a larger pattern, \zs and \ze are usually cleaner than building lookarounds.
/\S\zs\s\+$
A plain trailing-whitespace search like /\s\+$ also matches fully blank lines, which is noisy when you only want accidental spaces after real content.
\%(pattern\)\@=
Vim's lookahead assertion \@= confirms that the current position is followed by a pattern — without including those characters in the match.
[[:alpha:]]
Vim's regex engine supports POSIX character classes inside bracket expressions, giving you locale-aware, readable alternatives to manual character ranges like [
\_.{-}
The \ modifier in Vim extends any character class or atom to also match newlines.
\zs and \ze in a pattern
Vim's \zs ("match start") and \ze ("match end") atoms let you narrow the actual match region within a broader pattern context.
\%(...\)
Vim's standard grouping syntax \(.
\n in search, \r in replacement
Vim uses \n and \r differently depending on whether they appear in a search pattern or a replacement string, and mixing them up is a common source of confusion.
\@= and \@<=
Vim's regex engine supports zero-width lookahead and lookbehind assertions — \@= and \@<= — which let you match text based on surrounding context without in
\@<= and \@<!
Vim's \@<= and \@<! atoms let you write zero-width lookbehind assertions — they check what comes before the match position without consuming characters.
/\c
Vim lets you override the ignorecase and smartcase settings on a per-search basis using the \c (case-insensitive) and \C (case-sensitive) atoms directly inside
\@!
In Vim's regex engine, \@! is the negative lookahead assertion.