How do I write a Vim regex that matches any character including newlines for multi-line pattern matching?
Answer
\_.
Explanation
In Vim's regular expressions, . matches any character except a newline — the same as in most regex engines. To match any character including newlines, use \_. : the \_ prefix forces the character class to include the newline character. This unlocks true multi-line pattern matching directly in Vim's built-in search and substitution.
How it works
.— matches any single character except\n\_.— matches any single character including\n- The
\_modifier generalises to other classes:\_smatches whitespace plus newlines;\_[a-z]matches lowercase letters plus newlines
Example
Given text:
begin
first line
second line
end
Find everything from begin to end across lines:
/begin\_.\{-}end
\_.\{-} is the non-greedy form: it stops at the first end it finds. The greedy form \_.* would stretch to the last end in the buffer.
Tips
- Use
\_.\{-}(non-greedy) rather than\_.*(greedy) for most multi-line matches to avoid overshooting - Works in substitutions:
:%s/begin\_.\{-}end/REPLACED/replaces the entire multi-line block \nin a search pattern also matches newlines and is sometimes simpler for literal newline positions, but\_.is more composable when combined with repetition operators- For line-range operations,
:g/begin/.,/end/is often a cleaner alternative that works without crafting a multi-line regex