在perl中使用绑定运算符

时间:2015-11-11 14:09:14

标签: perl

我正在使用perl中的程序,我正在尝试在绑定运算符中组合多个正则表达式。我尝试使用下面的语法,但它不起作用。我想知道是否还有其他办法可以解决这个问题。

$in =~ (s/pattern/replacement/)||(s/pattern/replacement/)||...

5 个答案:

答案 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 -  -