0

这让我发疯了。帮助?

在我看来,它就像在 Perlforeach循环中一样,替换模式之外的变量按预期更改,但替换模式内的变量“卡住”了。就好像当 perls///在代码块中遇到替换模式时foreach,它会在循环中第一次插入替换模式的内容,然后再也不插入。

这是一些测试代码:

#!/usr/bin/perl

@replacements=("a", "b", "c");
@input=("xxletterxx");

foreach $replacement (@replacements) {
        foreach $line (@input) {
                $line=~s/xxletterxx/$replacement/g;
                print "R: $replacement\n";
                print "L: $line\n";
        }
}

我认为它应该打印这个:

R: a   
L: a   
R: b   
L: b   
R: c   
L: c

...但是它打印了这个:

R: a  
L: a  
R: b  
L: a  <--- Why isn't this 'b'?  
R: c  
L: a  <--- Why isn't this 'c'?  

请注意,“L”值在替换模式中仍然是“a”,即使在代码块的其他地方它随着@replacements?

这是为什么?

我觉得 Perl 突然坏了,或者我失去了理智。

看起来这种 DOS 行为几乎是在 perl 中发生的。

4

3 回答 3

6

这个循环控制:

foreach $line (@input)

$line的每个元素的别名,@input所以当你第一次进行替换时,你不仅改变了,而且也改变$line$input[0]。之后,xxletterxx就消失了,因此不再发生替换,因为/xxletterxx/不匹配。

为了使其按您想要的方式工作,您需要通过迭代@input数组的克隆来打破别名:

foreach $line (@{[@input]})

或者在修改它之前复制$line到另一个变量,$line在循环体中视为只读:

foreach $line (@input) {
        $modifiedline = $line;
        $modifiedline=~s/xxletterxx/$replacement/g;
        print "R: $replacement\n";
        print "L: $modifiedline\n";
}
于 2012-08-31T00:27:52.960 回答
0

正如霍布​​斯所说,问题是一旦你替换xxletterxxa,模式不再匹配,因此不会发生替换。我不确定你的最终目标是什么,但这有效

#!/usr/bin/env perl

use warnings;
use strict;

my @replacements=("a", "b", "c");

foreach my $replacement (@replacements) {
  my $line = "xxletterxx";
  $line=~s/xxletterxx/$replacement/g;
  print "R: $replacement\n";
  print "L: $line\n";
}

就像这个

#!/usr/bin/env perl

use warnings;
use strict;

my @replacements=("a", "b", "c");
my @lines = ("xxletterxx") x 3;

foreach my $replacement (@replacements) {
  my $line = shift @lines;
  $line=~s/xxletterxx/$replacement/g;
  print "R: $replacement\n";
  print "L: $line\n";
}

加上我已经为你添加strictwarnings:-)

编辑:一个可能更有趣的例子是对最后一个的修改,对于每个替换尝试@lines依次更改每个元素,并在替换成功后停止。

#!/usr/bin/env perl

use warnings;
use strict;

my @replacements=("a", "b", "c");
my @lines = ("xxletterxx") x 3;

foreach my $replacement (@replacements) {
  foreach my $line (@lines) {
    last if $line=~s/xxletterxx/$replacement/g;
  }

  print "R: $replacement\n";
  print "A: @lines\n";
}
于 2012-08-31T00:40:03.640 回答
0

没有xxletterxx可替换的borc因为您已经将其替换为a.

于 2012-08-31T00:28:37.543 回答