The easiest way to do this is with two substitutions:
$string =~ s/A/123/g;
$string =~ s/B/456/g;
or even (using an inline for
loop as a shorthand to apply multiple substitutions to one string):
s/A/123/g, s/B/456/g for $string;
Of course, for more complicated patterns, this may not produce the same results as doing both substitutions in one pass; in particular, this may happen if the patterns can overlap (as in A = YZ
, B = XY
), or if pattern B can match the string substituted for pattern A.
If you wish to do this in one pass, the most general solution is to use the /e
modifier, which causes the substitution to be interpreted as Perl code, as in:
$string =~ s/(A|B)/ $1 eq 'A' ? '123' : '456' /eg;
You can even include multiple expressions, separated by semicolons, inside the substitution; the last expression's value is what will be substituted into the string. If you do this, you may find it useful to use paired delimiters for readability, like this:
$string =~ s{(A|B)}{
my $foo = "";
$foo = '123' if $1 eq 'A';
$foo = '456' if $1 eq 'B';
$foo; # <-- this is what gets substituted for the pattern
}eg;
If your patterns are constant strings (as in the simple examples above), an even more efficient solution is to use a look-up hash, as in:
my %map = ('A' => '123', 'B' => '456');
$string =~ s/(A|B)/$map{$1}/g;
With this method, you don't even need the /e
modifier (although, for this specific example, adding it would make no difference). The advantage of using /e
is that it lets you implement more complicated rules for choosing the replacement than a simple hash lookup would allow.