Perl的foreach和更改循环变量

我在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...
}

但是有没有更有效的方式来完成这个?

非常感谢你!

解决方法

你不是疯了这是正常的行为.请参阅 perldoc perlsyn在Foreach循环下:

If any element of LIST is an lvalue,you can modify it by modifying VAR inside the
loop. Conversely,if any element of LIST is NOT an lvalue,any attempt to modify that
element will fail. In other words,the “foreach” loop index variable is an implicit
alias for each item in the list that you’re looping over.

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

06000


Note that $_ is an alias to the list value,so it can be used to modify the
elements of the LIST. While this is useful and supported,it can
cause bizarre results if the elements of LIST are not
variables. Using a regular “foreach” loop for this purpose would be
clearer in most cases.
See also “grep” for an array composed of those items
of the original list for which the BLOCK or EXPR evaluates to 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";
}

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...