How to match across multiple lines with /s modifier in Perl?
Question
How to match across multiple lines with /s modifier in Perl?
In Perl, matching patterns across multiple lines can sometimes be tricky because by default, the dot character . in a regex does not match newline characters. This means if your string contains line breaks (typically \n), the . metacharacter stops matching where the line ends.
To overcome this and allow . to match newline characters, Perl provides the /s modifier (often called the "single-line" mode or "dotall"). When you use /s, the dot matches every character including newline, allowing your match to span multiple lines.
Understanding /s vs /m
/schanges.to match any character, including newline\n./mtreats^and$as start/end of any line within the string, not just start/end of the entire string.
They are different and often confused: /s affects how . behaves, /m affects anchors (^ and $).
Example: Matching across multiple lines with /s
Suppose you want to match any content between <start> and <end> tags, even if there are multiple lines inside:
#!/usr/bin/perl
use strict;
use warnings;
my $text = "<start>This is
a multi-line
text<end>";
# Without /s modifier
if ($text =~ /<start>(.*)<end>/) {
print "Without /s: Matched: '$1'\n";
} else {
print "Without /s: No match\n";
}
# With /s modifier
if ($text =~ /<start>(.*)<end>/s) {
print "With /s: Matched: '$1'\n";
} else {
print "With /s: No match\n";
}
Output:
Without /s: No match
With /s: Matched: 'This is
a multi-line
text'
Explanation:
- Without
/s,.*stops at the first newline, so the whole pattern can't find<end>. - With
/s,.matches newlines, so.*greedily consumes all characters until it finds<end>.
Common Pitfalls
- Mixing
/sand/mexpecting the same behavior—remember,/mdoes not affect.. - Greedy vs lazy matching:
.*is greedy and matches as much as possible. For multiple matches in a single string, consider using the lazy quantifier.*?. - Line endings on different OS can be
\r\n(Windows), so matching\nspecifically might miss some cases. Using/shelps because it matches both. - If you only want to affect \^ and \$ (line anchors), use
/minstead.
Summary
The /s modifier in Perl regex is essential when you want the dot . to match newline characters, enabling matching over multiple lines within a string. It is a simple but powerful tool that helps avoid many common issues when dealing with multiline text data.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 5ms
Without /s: No match
With /s: Matched: 'This is
a multi-line
text'
(empty)Was this helpful?
Related Questions
- How to validate email addresses using Perl regex?
- How to split a string by regex pattern in Perl?
- How to use greedy vs non-greedy quantifiers in Perl regex?
- How to match start and end of string with ^ and $ in Perl?
- How to use alternation | in Perl regex?
- How to use the qr// operator to compile regex in Perl?