我正在研究perl中的程序,并且试图在绑定运算符中结合多个正则表达式。我曾尝试使用下面的语法,但它不起作用。我想知道是否还有其他方法可以解决这个问题。在perl中使用绑定运算符
$in =~ (s/pattern/replacement/)||(s/pattern/replacement/)||...
我正在研究perl中的程序,并且试图在绑定运算符中结合多个正则表达式。我曾尝试使用下面的语法,但它不起作用。我想知道是否还有其他方法可以解决这个问题。在perl中使用绑定运算符
$in =~ (s/pattern/replacement/)||(s/pattern/replacement/)||...
你可以经常得到关于Perl的使得使用B::Deparse一些代码有什么线索。
$ 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/;
更简单的方法可能是创建所有这些模式和替换的数组,然后简单地通过你的阵列迭代在次施加取代基的一种模式。
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;
}
@Kev您可以点击“接受”(复选标记)表示您已接受答案。 – Arc676
你可以得到的最接近的一个语法寻找类似于将
s/one/ONE/ or
s/two/TWO/ or
...
s/ten/TEN/ for $str;
这将尝试反过来每个取代,只有一次,第一次成功后,一个停止。
这并不完全清楚你需要什么,而且你完全不清楚你是否可以用你所建议的方式完成你看来想要的东西。 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 - -
使用for
为 “topicalize”(别名$_
到您的变量)。
for ($in) {
s/pattern/replacement/;
s/pattern/replacement/;
}
您能提供一些预期行为的例子吗?此外,您可以在正则表达式中使用'|'作为“或”。 – Arc676
使用上面的语法只是第一次替换,我也尝试过使用其他运算符 – Kev
用'or'分隔的表达式链将在其中一个表达式返回真值时始终停止。这就是布尔运算符被描述为“短路”时的意思。 –