How do I perform a non-greedy (minimal) match in Vim search?
Answer
.\{-}
Explanation
How it works
In most regex engines, *? or +? make quantifiers non-greedy (matching as little as possible). Vim uses a different syntax: \{-} is the non-greedy equivalent of *.
Here is the comparison:
.*matches as many characters as possible (greedy).\{-}matches as few characters as possible (non-greedy).\{-1,}is the non-greedy version of.\+(one or more, minimal).\{-,3}matches zero to three characters, preferring fewer
The \{-} quantifier is essential when you want to match the shortest possible string between two delimiters.
Example
Consider this HTML line:
<div class="header">Title</div><div class="content">Body</div>
With a greedy search:
/<div.*<\/div>
This matches the entire line from the first <div to the last </div>, capturing everything.
With a non-greedy search:
/<div.\{-}<\/div>
This matches only <div class="header">Title</div> -- the shortest possible match.
Another practical example is extracting quoted strings. Given:
name = "Alice", city = "Boston"
/".*"greedily matches"Alice", city = "Boston"(first quote to last quote)/".\{-}"matches just"Alice"(first quote to nearest closing quote)
In very magic mode (\v), the syntax is .{-} without the extra backslash:
/\v".{-}"