How do I write a non-greedy (lazy) quantifier in Vim's search regex?
Answer
\{-}
Explanation
In Vim's regex engine, \{-} is the non-greedy (lazy) quantifier — it matches as few characters as possible, unlike .* which matches as many as possible. This is Vim's equivalent of .*? in PCRE or other modern regex flavors. Non-greedy matching is essential when your pattern contains repeated delimiters and you want to match the shortest possible span.
How it works
.*— greedy: matches the longest possible string.\{-}— non-greedy: matches the shortest possible string\{-}is equivalent to*?in PCRE — zero or more, as few as possible\{-1,}— non-greedy one or more (equivalent to+?in PCRE)- Works in both search
/and substitute:%spatterns
Example
Given the line:
<b>bold</b> and <b>bolder</b>
Searching with /\<b\>.*\<\/b\> (greedy) matches the entire line from the first <b> to the last </b>.
Searching with /\<b\>.\{-}\<\/b\> (non-greedy) matches only <b>bold</b>, stopping at the first closing tag.
In a substitution:
:%s/<b>.\{-}<\/b>//g
This removes each <b>...</b> tag pair individually rather than consuming everything between the first and last tag.
Tips
- Use
\{-1,}for non-greedy one-or-more (like+?in PCRE) - Use
\{-n,m}for non-greedy bounded repetition - In
:set magic(default):\{-}requires backslash; in\v(very magic) mode: use{-}without backslash - Combine with
\zs/\zeto set match boundaries around a non-greedy span