我正在使用perl中的程序,我正在尝试在绑定运算符中组合多个正则表达式。我尝试使用下面的语法,但它不起作用。我想知道是否还有其他办法可以解决这个问题。
$in =~ (s/pattern/replacement/)||(s/pattern/replacement/)||...
答案 0 :(得分:2)
使用类似于
的语法,你可以得到最接近的语法s/one/ONE/ or
s/two/TWO/ or
...
s/ten/TEN/ for $str;
这将依次尝试每次替换,仅在第一次成功之后停止。
答案 1 :(得分:2)
您通常可以使用B::Deparse了解Perl对某些代码的构造。
$ perl -MO=Deparse -E'$in =~ (s/pattern1/replacement1/)||(s/pattern2/replacement2/)'
[ ... snip ... ]
s/pattern2/replacement2/u unless $in =~ s/pattern1/replacement1/u;
-e syntax OK
所以它尝试在$in
上进行首次替换。如果失败了,那就是尝试第二次替换。但它没有使用$in
进行第二次替换,而是使用$_
代替。
您在此处遇到优先问题。 Perl将您的代码解释为:
($in =~ s/pattern1/replacement1/) or (s/pattern2/replacement2/)
请注意,左括号已在$in
之前移动。
正如其他人所指出的,最好在这里使用循环方法。但我认为解释你的版本无法正常工作的原因可能很有用。
更新:要明确,如果您想使用这样的语法,那么您需要:
($in =~ s/pattern1/replacement1/) or
($in =~ s/pattern2/replacement2/);
请注意,我在每个表达式中都包含$in =~
。在这一点上,很明显(我希望)为什么循环解决方案更好。
但是,由于or
是一个短路运算符,因此该语句将在第一次成功替换后停止。我假设您在原始代码中使用它时想要的是什么。如果那不是您想要的,那么您需要切换到使用and
或(在我看来更好)将它们分成单独的语句。
$in =~ s/pattern1/replacement1/;
$in =~ s/pattern2/replacement2/;
答案 2 :(得分:2)
使用for
来"使用主题化" (将变量$_
别名)。
for ($in) {
s/pattern/replacement/;
s/pattern/replacement/;
}
答案 3 :(得分:1)
一种更简单的方法可能是创建一个包含所有这些模式和替换的数组,然后简单地遍历数组,一次应用替换一个模式。
my $in = "some string you want to modify";
my @patterns = (
['pattern to match', 'replacement string'],
# ...
);
$in = replace_many($in, \@patterns);
sub replace_many {
my ($in, $replacements) = @_;
foreach my $replacement ( @$replacements ) {
my ($pattern, $replace_string) = @$replacement;
$in =~ s/$pattern/$replace_string/;
}
return $in;
}
答案 4 :(得分:0)
根本不清楚你需要什么,而且你完全不清楚你能用你建议的方式完成你想要的东西。 OR运算符是一个短路运算符,您可能不希望出现这种情况。请举例说明您期望的输入和您想要的输出,希望每个输出的几个例子。同时,这是一个测试脚本。
use warnings;
use strict;
my $in1 = 'George Walker Bush';
my $in2 = 'George Walker Bush';
my $in3 = 'George Walker Bush';
my $in4 = 'George Walker Bush';
(my $out1 = $in1) =~ s/e/*/g;
print "out1 = $out1 \n";
(my $out2 = $in2) =~ s/Bush/Obama/;
print "out2 = $out2 \n";
(my $out3 = $in3) =~ s/(George)|(Bush)/Obama/g;
print "out3 = $out3\n";
$in4 =~ /(George)|(Walker)|(Bush)/g;
print "$1 - $2 - $3\n";
exit(0);
在最后一种情况下,您会注意到只有第一个OR运算符在正则表达式中匹配。如果你想取代乔治沃克布什'与巴拉克侯赛因奥巴马一起,你可以轻松地做到这一点,但你也可以用“巴拉克华盛顿”取代“华盛顿乔治华盛顿”。 - 这是你想要的吗?以下是脚本的输出:
out1 = G*org* Walk*r Bush
out2 = George Walker Obama
out3 = Obama Walker Obama
Use of uninitialized value $2 in concatenation (.) or string at pq_151111a.plx line 19.
Use of uninitialized value $3 in concatenation (.) or string at pq_151111a.plx line 19.
George - -