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

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 :%s patterns

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 / \ze to set match boundaries around a non-greedy span

Next

How do I delete all lines matching my last search pattern without retyping it?