How do I search for a pattern that spans multiple lines?
Answer
/pattern1\_.*pattern2
Explanation
Vim's \_ modifier makes any character class match newlines too. The pattern \_.* matches any character including newlines, letting you search across line boundaries.
How it works
.matches any character except newline\_.*matches any character including newline (zero or more times)\_smatches whitespace including newlines\_^matches the start of any line (not just the first)
Examples
" Find 'function' followed by 'return' anywhere after (across lines)
/function\_.*return
" Find opening brace followed by closing brace (multi-line)
/{\_.*}
" Find empty HTML tags (across lines)
/<div>\_s*<\/div>
" Find 'if' followed by 'else' within a few lines
/if\_.*\%3lelse
Line-boundary atoms
\n " Match a newline character in the search
\_s " Whitespace or newline
\_^ " Start of a line (anywhere in match)
\_$ " End of a line (anywhere in match)
\_[a-z] " Character class that also matches newline
Practical example
Find Python functions with no return statement:
/def \w\+(.*)\_.*\(return\)\@!\ndef
Tips
- Multi-line searches can be slow on large files since Vim must scan across lines
- Use
\_.\{-}for non-greedy multi-line matching (like.*?in other regex flavors) - Combine with
\v(very magic) for cleaner syntax:/\vfunction\_.+return - This works in both
/search and:ssubstitution commands