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

How do I write a Vim search pattern that matches text spanning multiple lines?

Answer

/pattern1\_.{-}pattern2

Explanation

Vim's regex engine normally treats . as matching any character except a newline, making cross-line matches impossible. The \_ prefix turns any character class or . into a newline-aware version, enabling true multi-line search patterns.

How it works

  • \_. — matches any single character including newlines (unlike . which stops at end-of-line)
  • \_.{-} — non-greedy match of any characters including newlines ({-} is Vim's non-greedy quantifier)
  • \_s — matches any whitespace including newlines (\s only matches inline whitespace)
  • \_[abc] — matches a, b, c, or a newline

Example

Given a buffer:

function foo(
    arg1,
    arg2
)

To find foo(...) even when the argument list spans multiple lines, use the non-greedy form:

/foo(\_.{-})

The greedy \_.* would match from the first ( all the way to the last ) in the file. Always prefer {-} with multi-line patterns to avoid over-matching.

Tips

  • Combine with \zs / \ze to narrow the highlighted region: /foo(\zs\_.{-}\ze) highlights only the argument content
  • \_s\+ is a useful pattern for collapsing runs of whitespace that may include blank lines
  • Use :set hlsearch and n / N to visually confirm multi-line match boundaries
  • In substitute commands, \n in the replacement inserts a literal newline, while \_. in the pattern matches across newlines

Next

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