代码之家  ›  专栏  ›  技术社区  ›  KLee1

Perl的foreach和改变循环变量

  •  15
  • KLee1  · 技术社区  · 14 年前

    我正在用Perl编写一个脚本,对Perl的 foreach 构造。

    如果您更改其中一个循环变量,它将在实际数组中更改。事实上是这样,还是我做了什么 完全地

    我想换一根绳子 abc.abc#a abc_abc_a (下划线表示非字母数字字符),但我需要保留数组中的原始值以供以后使用。

    我有这样的代码:

    @strings = ('abc.abc#a', 'def.g.h#i');
    foreach my $str (@strings){
        $str =~ s/[^0-9A-Za-z]/_/g;
        print $str, "\n"; #Actually I use the string to manipulate files.
    }
    

    @strings = ('abc.abc#a', 'def.g.h#i');
    foreach my $str (@strings){
        my $temp = $str; #copy to a temporary value
        $temp =~ s/[^0-9A-Za-z]/_/g;
        print $temp, "\n"; #$str remains untouched...
    }
    

    但是有没有更有效的方法来实现这一点呢?

    非常感谢你!

    4 回复  |  直到 14 年前
        1
  •  16
  •   Ether    14 年前

    你没有疯;这是正常的行为。看到了吗 perldoc perlsyn 在Foreach循环下:

    如果列表中的任何元素是左值,则可以通过在 循环。相反,如果列表中的任何元素不是左值,则任何修改该元素的尝试 循环列表中每个项目的别名。

    其他循环迭代器,如 map 有类似行为:

    map BLOCK LIST  
    map EXPR,LIST
    


    请注意,$是列表值的别名,因此可以使用它来修改 列表的元素。虽然这是有用的和支持的,但它可以 如果列表中的元素不是 在大多数情况下更清晰。 有关由这些项组成的数组,请参见“grep” 块或表达式计算结果为true的原始列表的。

    您可以这样重写代码,这样至少可以避免添加额外的行:

    my @strings = ('abc.abc#a', 'def.g.h#i');
    foreach my $str (@strings){
        (my $copy = $str) =~ s/[^0-9A-Za-z]/_/g;
        print $copy, "\n";
    }
    
        2
  •  3
  •   MkV    14 年前

    在修改数组中的元素之前,始终可以制作数组的副本 my '添加以安抚 strict

    my @strings = ('abc.abc#a', 'def.g.h#i');
    foreach my $str (my @temp = @strings) {
        $str =~ s/[^0-9A-Za-z]/_/g;
        print "$str\n"; #Actually I use the string to manipulate files.
    }
    use Data::Dumper;
    print Dumper(\@strings);
    

    abc_abc_a
    def_g_h_i
    $VAR1 = [
              'abc.abc#a',
              'def.g.h#i'
            ];
    

    @temp 不在范围之外 foreach 循环。

        3
  •  2
  •   David Harris    14 年前

    Programming Perl 状态下,循环变量是当前数组元素的别名,如果任何修改都不影响原始值,则必须保存循环变量。

        4
  •  1
  •   DontVoteMeDown    11 年前
    my @strings = ('abc.abc#a', 'def.g.h#i');
    
    print join( "\n", ( map { $_ =~ s/[^0-9A-Za-z]/_/gr } @strings ) )."\n";
    

    这个 r 5.14 向上。