Reputation: 2589
My Input:
$brackets = '\left \right \center \right \left \middle';
On the above string I need to replace every \left
string into (
opening braces and every \right
string into )
closing braces.
I am able to replace in few methods to get the output. However I want to know how can we done this in r
modifier. Here is what I have so far
$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
I don't know where could I find my mistake.
Upvotes: 0
Views: 321
Reputation:
It is fairly easy to just build a list of replacements.
use strict;
use warnings;
my $brackets = '\left \right \center \right \left \middle';
for ( $brackets ) {
s/\\left/(/g;
s/\\right/)/g;
}
print $brackets, "\n";
obviously you can still add to the list and remove whitespace as well.
More information about this method:
Upvotes: 0
Reputation: 118156
For this literal question which involves only two substrings to be replaced, you should use two separate s///
as @Patrick85 recommends. The approach below begins to make sense only if you have 3 or more such replacements. In that case, tucking the mapping away in a hash will make your code clearer.
Use a hash to look up replacements:
#!/usr/bin/env perl
use strict;
use warnings;
my %replacement = (
'\left' => '(',
'\right' => ')'
);
my $s = '\left \right \center \right \left \middle';
my $t = $s =~ s/( \\ (?: left | right ))/$replacement{$1}/rgx;
print "$s\n$t\n";
There are many problems with trying to cram everything into a single line:
$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
It is hard to read. Also, it is impossible to generalize. What happens if you need to map N strings to their replacements? Let's try to write this a little more clearly by adding some whitespace:
$brackets =~ s{
\\
(left | right)
}{
$& =~ s/\\left/\(/r &&
$& =~ s/\\right/\)/gr;
}gex;
Even if this did what you wanted, you've now replaced a single s///
coupled with a simple hash lookup with something that does two additional s///
operations for each match in your source string.
For the example string you showed, this one would do eight additional s///
operations.
That is not good.
Upvotes: 6
Reputation: 2589
Just I need to close this my Question. And the answer provided by @Wiktor Stribiżew [in Comment] on my question.
$brackets = '\left \right \center \right \left \middle';
My Request:
$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
Answer:
$brackets=~s/\\((left)|right)/$2 ? '(' : ')'/eg;
Upvotes: -4
Reputation: 580
Use two simple substitutions instead of one complicated one:
#!/usr/bin/env perl
use strict;
use warnings;
my $brackets = '\left \right \center \right \left \middle';
$brackets =~ s/\\left/(/g;
$brackets =~ s/\\right/)/g;
print $brackets."\n";
Output:
( ) \center ) ( \middle
Upvotes: 5