According to perlvar:
Variables related to regular expressions
These variables are read-only
and dynamically-scoped, unless we note otherwise. The dynamic nature
of the regular expression variables means that their value is limited
to the block that they are in.
Traditionally in Perl, any use of any of the three variables,
oranywhere in the code, caused
all subsequent successful pattern matches to make a copy of the
matched string, in case the code might subsequently access one of
"in case the code might subsequently access one of those variables"
my $s = "Hello world";
$s =~ s/Hello //;
"all subsequent matches in that block"
my $s = "no\n yesHello world";
$s =~ /yes/ and say $'; # Note the use of $'
$s = '12' x 1_000_000;
my $n = () = $s =~ /2/g;
say "Found $n matches";
$s =~ /2/g
In Perl 5.18.0 onwards, perl started noting the presence of each of
the three variables separately, and only copied that part of the
In Perl 5.20.0 a new copy-on-write system was enabled by default,
which finally fixes all performance issues with these three variables,
and makes them safe to use anywhere.
It has to copy the string because the original variable may have been modified between the regex match and the time the match variables are used:
my $var = "foobar"; $var =~ /.../ or die; $var = "hello"; print "$& $'"; # outputs "foo bar"
It has to effectively make a copy of the whole string because that's what
$` . $& . $' results in. As you quoted yourself, in perl 5.18 someone realized that you could track each variable separately and thus only copy the part before the match (or the match itself, or the part after the match) if only that variable appears in the code:
In Perl 5.18.0 onwards, perl started noting the presence of each of the three variables separately, and only copied that part of the string required
The match variables are global. You could at any time call a function (that calls a function that calls a function ...) that accesses
$', so perl has to do a full copy after each successful regex match if those variables have been seen anywhere in the code. (Basically, perl can't statically determine that a particular piece of code is never going to access those match variables and thus avoid the copy.)