How to Search for Patterns That Span Multiple Lines in ripgrep
To search for patterns that span multiple lines in ripgrep, enable multiline mode with the -U or --multiline flag, which allows the regex engine to match across newline characters.
Ripgrep processes files line-by-line by default, preventing regular expressions from crossing line boundaries. This guide explains how to configure the BurntSushi/ripgrep tool to match patterns that extend across multiple lines using the core flags defined in the source code.
Enabling Multiline Mode with the -U Flag
By default, ripgrep restricts matches to single lines, which means a match cannot contain a newline character. To lift this restriction, use the -U (or --multiline) flag, which permits patterns to match across line terminators.
According to the source code in crates/core/flags/defs.rs, the -U/--multiline option "enables searching across multiple lines" by treating the input as a single continuous string rather than discrete lines. When this flag is active, a pattern such as foo\nbar will successfully match the literal two-line sequence where foo appears on one line and bar appears on the next.
Dot-All Mode and the Dot Metacharacter
Even with multiline mode enabled, the dot (.) metacharacter does not match newline characters by default. To allow . to span across lines, you must enable dot-all mode using the --multiline-dotall flag or embed the (?s) directive directly in your regex pattern.
The user guide in GUIDE.md documents this interaction, noting that multiline mode handles the line-crossing behavior while dot-all mode controls whether the dot metacharacter matches newlines.
Performance Implications of Multiline Searching
Multiline mode fundamentally changes how ripgrep processes files, forcing the tool to read the entire file into memory (or fully memory-map it) before executing the search. This behavior increases memory consumption and may reduce search speed when processing very large files, as the engine can no longer stream through content line-by-line.
Practical Command-Line Examples
The test suite in tests/multiline.rs validates several common multiline use cases. Here are practical examples based on the implementation:
Match a literal two-line sequence:
rg -U 'abc\ndef' path/to/file
Allow . to match newlines for flexible pattern matching:
rg -U --multiline-dotall 'of this world.+detective work' sherlock.txt
Extract only the matched text without printing entire lines:
rg -U --only-matching 'Watson|Sherlock\p{Any}+?Holmes' file.txt
Generate Vim-compatible output for multiline matches:
rg -U --vimgrep 'Watson|Sherlock\p{Any}+?Holmes' file.txt
Summary
- Use
-Uor--multilineto enable patterns that match across line breaks in ripgrep, lifting the default restriction against newline characters in matches - Combine with
--multiline-dotallor the embedded(?s)flag to allow the.metacharacter to match newline characters when spanning lines - Expect higher memory usage because multiline mode requires loading entire files into memory rather than streaming line-by-line
- Consult the implementation in
crates/core/flags/defs.rsand test cases intests/multiline.rsfor advanced usage patterns and edge cases
Frequently Asked Questions
Why doesn't my pattern match across lines even with the -U flag?
The -U flag allows explicit newline characters (\n) in your pattern to match, but the dot (.) metacharacter still excludes newlines by default. If your pattern relies on . to span lines, you must add the --multiline-dotall flag or include (?s) at the start of your regex to enable dot-all mode according to the flag definitions in crates/core/flags/defs.rs.
How does multiline mode affect ripgrep's performance?
Multiline mode prevents ripgrep from using its default streaming architecture. Instead of processing files line-by-line, the tool must load the entire file content into memory (or memory-map the whole file) before searching, which increases RAM usage and may slow down searches on very large files.
Can I use multiline mode with ripgrep's replacement functionality?
Yes, multiline mode works with replacement operations, allowing you to replace patterns that span multiple lines. Ensure you use the -U flag along with the replacement flag -r (or --replace), and remember that capture groups can reference text across line boundaries when multiline mode is active.
Where are the multiline search options defined in the ripgrep source code?
The command-line flags are defined in crates/core/flags/defs.rs, which contains the documentation and implementation for both --multiline and --multiline-dotall. Comprehensive test cases demonstrating expected behavior are located in tests/multiline.rs, while user-facing documentation appears in GUIDE.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →