我的输入:
$brackets = '\left \right \center \right \left \middle';
在上面的字符串中,我需要将每个\left
字符串替换为(
个大括号,将每个\right
字符串替换为)
个大括号。
我可以用几种方法替换以获得输出。但是我想知道如何在r
修饰符中完成此操作。这是我到目前为止所拥有的
$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
我不知道在哪里可以找到我的错误。
答案 0 :(得分:6)
对于只涉及两个要替换的子字符串的文字问题,您应该使用两个单独的s///
作为@Patrick85 recommends。只有当你有3个或更多这样的替代品时,下面的方法才有意义。在这种情况下,将映射隐藏在散列中将使您的代码更清晰。
使用哈希查找替换:
#!/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";
尝试将所有内容整合到一行中有很多问题:
$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
很难读懂。而且,不可能概括。如果您需要将 N 字符串映射到其替换项,会发生什么?让我们尝试通过添加一些空格来更清楚地写这个:
$brackets =~ s{
\\
(left | right)
}{
$& =~ s/\\left/\(/r &&
$& =~ s/\\right/\)/gr;
}gex;
即使这样做了你想要的,你现在已经用一个简单的哈希查找替换了一个s///
,并且对源字符串中的每个匹配执行了两次额外的s///
操作。< / p>
对于您展示的示例字符串,此字符串将执行 八 其他s///
操作。
这不好。
答案 1 :(得分:5)
使用两个简单的替换而不是一个复杂的替换:
#!/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";
输出:
( ) \center ) ( \middle
答案 2 :(得分:0)
建立一个替换列表相当容易。
use strict;
use warnings;
my $brackets = '\left \right \center \right \left \middle';
for ( $brackets ) {
s/\\left/(/g;
s/\\right/)/g;
}
print $brackets, "\n";
显然你仍然可以添加到列表中并删除空格。
答案 3 :(得分:-4)
我需要关闭这个问题。答案由@Wiktor Stribiżew [评论]提供给我的答案。
$brackets = '\left \right \center \right \left \middle';
我的要求:
$brackets=~s{\\(left|right)}{$&=~s/\\left/\(/r && $&=~s/\\right/\)/gr; }ge;
答案:
$brackets=~s/\\((left)|right)/$2 ? '(' : ')'/eg;