--- name: s/// signature: 's/PATTERN/REPLACEMENT/msixpodualngcer' since: 5.0 status: documented categories: ["Regular expressions and pattern matching"] --- ```{index} single: s///; Perl built-in ``` *[Regular expressions and pattern matching](../perlfunc-by-category)* # 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 [`$_`](../perlvar). The target must be a scalar lvalue — a variable, an array or hash element, or a [`substr`](substr) / assignment producing one — unless the `/r` flag is used, which works on any value and returns the modified copy. ## Synopsis ```perl 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. ```perl 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 - [`$_`](../perlvar) — the default target when no `=~` or `!~` is given. `s/old/new/` with no binding reads and writes [`$_`](../perlvar). - [`$&`](../perlvar), [`$\``](../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`](pos) — cleared on the target scalar by a successful non-`/g` substitution; under `/g` it advances with each match and can be inspected between iterations. - The **last successful pattern** — used when `PATTERN` evaluates to the empty string (`s//new/` re-uses the last successful regex from this scope). - [`$/`](../perlvar), [`$\`](../perlvar) 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//`](m) and [`qr`](qr); see [`perlre`](../perlre) for the match-side details. Replacement-specific flags: - `e` — evaluate `REPLACEMENT` as a block of Perl code. The block's value is the replacement string. Equivalent to wrapping it in `do { ... }` and stringifying the result. - `ee` — evaluate as code, then `eval` the resulting string again. Equivalent to `eval(do { REPLACEMENT })`. Additional `e` modifiers add more `eval` layers. - `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 with [`m//`](m) but has no behavioural effect on `s///`; triggers a warning under `use 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`](../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: ```perl s(foo)(bar) s{foo}{bar} s/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): ```perl 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 [`$_`](../perlvar): ```perl $_ = 'the quick brown fox'; s/quick/slow/; # $_ is now 'the slow brown fox' ``` Explicit target with `=~`: ```perl my $path = '/usr/bin/perl'; $path =~ s|/usr/bin|/usr/local/bin|; # $path is '/usr/local/bin/perl' ``` Global replacement, capturing the count: ```perl 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`](map): ```perl 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: ```perl 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: ```perl my $out = $text =~ s/foo/bar/r =~ s/baz/qux/r; ``` Capture groups and backreferences in the replacement — note the `$1` form, not `\1`: ```perl # swap the first two whitespace-separated fields s/(\S+)\s+(\S+)/$2 $1/; ``` The `1 while` idiom for substitutions that create new matches: ```perl # 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, or [`substr`](substr) lvalue. `s/x/y/` against a string literal or the result of a function call is a compile-time error. Under `/r` any expression is fair game since nothing is modified. - **Empty pattern re-uses the last successful match.** `s//new/` substitutes against whatever `PATTERN` most recently matched in the enclosing scope. Convenient inside `while (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 `$foo` changes. Use `/o` to compile once and freeze the captured value — or precompile with [`qr`](qr), which is the modern alternative. - **`/e` parses 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 extra `e` wraps one more [`eval`](eval) around the value. - **`/g` with an empty match advances by one character** to avoid an infinite loop: `s/\b/-/g` inserts between every token, it does not hang at the first position. - **`!~` flips the return**, not the work. `$x !~ s/A/a/g` still modifies `$x`; it just returns true when no `A` was found. - **Delimiter matching for brackets** uses the mirrored closer: `s{pat}{rep}`, `s`. A delimiter other than a bracket must appear three times total: `s/pat/rep/`. - **`/c` is a no-op on `s///`**. Accepted for parser symmetry with [`m//`](m); using it produces a warning under `use warnings` and nothing more. - **Assignment-as-target idiom.** `($copy = $src) =~ s/x/y/g` populates `$copy` with the modified value and leaves `$src` alone. Modern code prefers `my $copy = $src =~ s/x/y/gr`. - **Tied or overloaded targets.** Without `/r`, `STORE` is 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 `/r` the 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//`](m) — the matching operator; shares match-side flag semantics and return-vs-context rules - [`tr///`](tr) — character-by-character transliteration; much faster when the job is literal character translation, not a regex - [`qr//`](qr) — precompile a pattern once and interpolate it into many `s///` or `m//` calls; the modern alternative to `/o` - [`split`](split) — when the goal is to break a string on a pattern rather than replace matches, reach for `split` instead - [`perlre`](../perlre) — the full pattern-language reference; every match-side flag on `s///` is defined there - [`$&`](../perlvar) — the matched text, available inside the `REPLACEMENT` of every `s///`