How do I write a Vim regex that matches across multiple lines?
Answer
\_.\+
Explanation
By default, . in a Vim regex matches any character except a newline. Prefixing a character class with \_ makes it also match newlines, allowing patterns to span multiple lines. The most general form is \_. — which matches any single character including \n — and \_.\+ or \_.\* for multi-line spans.
How it works
\_— a prefix that adds newline to the next character class\_.— matches any character, including a newline (equivalent to[\s\S]in other engines)\_s— matches any whitespace including newlines\_a— matches any alphanumeric character or newline
Example
To delete a C-style block comment that may span multiple lines:
:s/\/\*\_.\{-}\*\///
The \{-} is a non-greedy quantifier, preventing it from matching too much. Without \_, the . would stop at the first newline and the pattern would fail to match a multi-line comment.
To search for a function call whose arguments may wrap:
/myFunc(\_.\{-})
Tips
- Always prefer non-greedy
\{-}over*with\_.to avoid matching too far - Use
\_.\{-}where you would write[\s\S]*?in PCRE or JavaScript regex - In
\vvery-magic mode, write\_.the same way — the\_prefix still works - This also works in
:substitute,:global, and:vimgreppatterns