Regular expressions and pattern matching
s///#
Search a string for a pattern and replace every match with a replacement.
s/// is Perl’s substitution operator. It finds text matching PATTERN
in the target string, replaces each match with REPLACEMENT, and by
default returns the number of substitutions made. With no explicit
target (no =~ or !~), it operates on $_. The target
must be a scalar lvalue — a variable, an array or hash element, or
a substr / assignment producing one — unless the /r
flag is used, which works on any value and returns the modified copy.
Synopsis#
s/PATTERN/REPLACEMENT/FLAGS
$str =~ s/PATTERN/REPLACEMENT/FLAGS
$str !~ s/PATTERN/REPLACEMENT/FLAGS
my $copy = $str =~ s/PATTERN/REPLACEMENT/r
What you get back#
By default, the count of substitutions performed as an integer:
0 when nothing matched (which is false in boolean context), a
positive integer on success. The target scalar is modified in place.
With the /r flag, the semantics flip: the target is not modified,
and the operator returns the (possibly changed) string. If nothing
matched, /r still returns a copy of the original. The result of /r
is always a plain string, even when the source is a tied variable or
a blessed object with overloading.
!~ inverts the boolean sense of the return value: it yields true
when nothing was substituted, false when at least one substitution
happened. The target is still modified either way.
my $n = ($text =~ s/foo/bar/g); # count of replacements
my $out = $text =~ s/foo/bar/r; # copy-and-modify, $text untouched
Global state it touches#
$_— the default target when no=~or!~is given.s/old/new/with no binding reads and writes$_.$&, [`$``](../perlvar), [`$’`](../perlvar), [`$1`](../perlvar) and friends — set by each successful match, the same way [`m//`](m) sets them. Inside `REPLACEMENT` they refer to the current match, not any earlier one.pos— cleared on the target scalar by a successful non-/gsubstitution; under/git advances with each match and can be inspected between iterations.The last successful pattern — used when
PATTERNevaluates to the empty string (s//new/re-uses the last successful regex from this scope).$/,$\and output separators are not touched —s///produces a string, it does not write one.
Flags#
The full set is msixpodualngcer. Match-side flags behave exactly
as in m// and qr; see perlre for the
match-side details. Replacement-specific flags:
e— evaluateREPLACEMENTas a block of Perl code. The block’s value is the replacement string. Equivalent to wrapping it indo { ... }and stringifying the result.ee— evaluate as code, thenevalthe resulting string again. Equivalent toeval(do { REPLACEMENT }). Additionalemodifiers add moreevallayers.r— non-destructive: leave the target unchanged and return the modified copy (or an unchanged copy on no match). Cannot be combined with a non-scalar-lvalue target restriction — any expression is a valid target under/r.g— global: replace every non-overlapping match, not just the first.c— accepted for syntactic symmetry withm//but has no behavioural effect ons///; triggers a warning underuse warnings.
Match-side flags in one line:
m (multiline ^/$), s (. matches newline), i
(case-insensitive), x / xx (extended whitespace, comments),
p (preserve match variables; obsolete since 5.20), o (compile
pattern once), d / u / a / l (character-set semantics),
n (non-capturing by default). See perlre.
Delimiters#
Any non-whitespace character may replace /. If the chosen delimiter
is one of (, [, {, or <, the operator takes two bracketed
groups and a delimiter between them is optional:
s(foo)(bar)
s{foo}{bar}
s<foo>/bar/
s[foo]{bar}g
Single-quote delimiters turn off interpolation in both PATTERN and
REPLACEMENT (unless /e is in force, which always parses
REPLACEMENT as code):
s'$name'$value'; # literal $name → literal $value, no interpolation
Backticks are ordinary delimiters; s`x`y` does not run a shell
command.
When the delimiter is a character that is also an identifier
character, a space after the s is required so the parser does not
read it as part of the operator name.
Examples#
Basic in-place substitution on $_:
$_ = 'the quick brown fox';
s/quick/slow/; # $_ is now 'the slow brown fox'
Explicit target with =~:
my $path = '/usr/bin/perl';
$path =~ s|/usr/bin|/usr/local/bin|;
# $path is '/usr/local/bin/perl'
Global replacement, capturing the count:
my $text = 'one two two three two';
my $n = ($text =~ s/two/2/g); # $text: 'one 2 2 three 2'; $n == 3
Non-destructive /r — leaves the source alone, returns the copy.
Idiomatic in map:
my @clean = map { s/\s+\z//r } @lines; # @lines untouched
Code evaluation with /e. The right-hand side is a Perl expression
whose value becomes the replacement:
my $s = 'abc123xyz';
$s =~ s/\d+/$& * 2/e; # $s is 'abc246xyz'
my %percent = (n => "\n", t => "\t");
$s =~ s/%(.)/$percent{$1} || $&/ge; # expand %-escapes
Chained /r — pure-functional transforms with no intermediate
variable:
my $out = $text =~ s/foo/bar/r
=~ s/baz/qux/r;
Capture groups and backreferences in the replacement — note the $1
form, not \1:
# swap the first two whitespace-separated fields
s/(\S+)\s+(\S+)/$2 $1/;
The 1 while idiom for substitutions that create new matches:
# insert commas into an integer from the right
my $n = '1234567890';
1 while $n =~ s/(\d)(\d\d\d)(?!\d)/$1,$2/;
# $n is '1,234,567,890'
Edge cases#
Target must be a scalar lvalue (unless
/r): a variable, element, orsubstrlvalue.s/x/y/against a string literal or the result of a function call is a compile-time error. Under/rany expression is fair game since nothing is modified.Empty pattern re-uses the last successful match.
s//new/substitutes against whateverPATTERNmost recently matched in the enclosing scope. Convenient insidewhile (m/.../g) { s//x/ }, surprising when unrelated code has run in between.Interpolation happens at runtime.
s/$foo/$bar/recompiles the pattern every call if$foochanges. Use/oto compile once and freeze the captured value — or precompile withqr, which is the modern alternative./eparses the replacement at compile time even though it runs at match time. Syntax errors surface when the script is loaded, not when the substitution fires. Each extraewraps one moreevalaround the value./gwith an empty match advances by one character to avoid an infinite loop:s/\b/-/ginserts between every token, it does not hang at the first position.!~flips the return, not the work.$x !~ s/A/a/gstill modifies$x; it just returns true when noAwas found.Delimiter matching for brackets uses the mirrored closer:
s{pat}{rep},s<pat><rep>. A delimiter other than a bracket must appear three times total:s/pat/rep/./cis a no-op ons///. Accepted for parser symmetry withm//; using it produces a warning underuse warningsand nothing more.Assignment-as-target idiom.
($copy = $src) =~ s/x/y/gpopulates$copywith the modified value and leaves$srcalone. Modern code prefersmy $copy = $src =~ s/x/y/gr.Tied or overloaded targets. Without
/r,STOREis invoked after the substitution to write the new value back; the fetched value is copied into a plain buffer before the pattern is applied. With/rthe result is always a plain string — tie / overloading is not preserved in the return.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
m//— the matching operator; shares match-side flag semantics and return-vs-context rulestr///— character-by-character transliteration; much faster when the job is literal character translation, not a regexqr//— precompile a pattern once and interpolate it into manys///orm//calls; the modern alternative to/osplit— when the goal is to break a string on a pattern rather than replace matches, reach forsplitinsteadperlre— the full pattern-language reference; every match-side flag ons///is defined there$&— the matched text, available inside theREPLACEMENTof everys///