How do I take multiple notes using Perl?
A hash can do what you want:
#!/usr/bin/perl
use strict;
use warnings;
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my %replace = (
"+" => " ",
dog => "cat",
);
$s =~ s/([+]|dog)/$replace{$1}/g;
print "$s\n";
I see in the comments that you are interested in performance, the two regex solutions are more performant. This is because any solution that works for a single regex will have to use captures (which slow down the regex).
Below are the test results:
eval: The quick brown fox jumps over the lazy cat that is my cat
hash: The quick brown fox jumps over the lazy cat that is my cat
two: The quick brown fox jumps over the lazy cat that is my cat
Rate hash eval two
hash 33184/s -- -29% -80%
eval 46419/s 40% -- -72%
two 165414/s 398% 256% --
I used the following test:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my %replace = (
"+" => " ",
dog => "cat",
);
my %subs = (
hash => sub {
(my $t = $s) =~ s/([+]|dog)/$replace{$1}/g;
return $t;
},
two => sub {
(my $t = $s) =~ s/[+]/ /g;
$t =~ s/dog/cat/g;
return $t;
},
eval => sub {
(my $t = $s) =~ s/(\+)|(dog)/$1 ? ' ' : 'cat'/eg;
return $t;
},
);
for my $k (sort keys %subs) {
print "$k: ", $subs{$k}(), "\n";
}
Benchmark::cmpthese -1, \%subs;
a source to share
Perl 5.14 and newer has a non-destructive chaining capability so you can kill 3 birds with one stone: do your two globals and assign the result to a new variable without changing the original variable.
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my $result = $s =~ s/+/ /gr
=~ s/dog/cat/gr;
Replace all of yours with a +
space and replace each dog
with cat
, assigning the result to a new variable. In one line space.
a source to share
If speed is important, you should probably stick to two lines. But when I need to do multiple substitutions at once, I usually care more about convenience, so I use the hash as suggested by Hour. Owens. Two advantages over the two-line layer are that it is easy to modify and behaves as expected (for example, replacing "cat" for "dog" and "dog" for "cat" at the same time).
However, I am very lazy to write the regex by hand and prefer to collect it with a join, and use a map to remove stuff:
#!/usr/bin/perl
use strict;
use warnings;
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my %replace = (
"+" => " ",
dog => "cat",
);
my $regex = join "|",
#use quotemeta to escape special characters
map { quotemeta }
#reverse sort the keys because "ab" =~ /(a|ab)/ returns "a"
sort { $b cmp $a } keys %replace;
#compiling the regex before using it prevents
#you from having to recompile it each time
$regex = qr/$regex/;
$s =~ s/($regex)/$replace{$1}/g;
print "$s\n";
a source to share