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

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 \v very-magic mode, write \_. the same way — the \_ prefix still works
  • This also works in :substitute, :global, and :vimgrep patterns

Next

How do I build a macro programmatically using Vimscript instead of recording it?