当我运行以下语句时:
@filtered = map {s/ //g} @outdata;
它返回一个空列表,而不是我期望的过滤列表。我要做的是
从字符串数组(这是一个 XML 文件)中删除每次出现的 。
显然,我不明白一些事情。谁能告诉我这样做的正确方法可能是,为什么这对我不起作用?
请注意, map 也将修改您的源数组。所以你可以这样做:
map {s/ //g} @outdata;
并完全跳过 @filtered 变量,或者如果您需要保留原件,
@filtered = @outdata;
map {s/ //g} @filtered;
虽然在这种情况下,使用 foreach 可能更具可读性:
s/ //g foreach @filtered;
试试这个:
@filtered = map {s/ //g; $_} @outdata;
问题是 perl 中的 s 运算符修改了 $_ 但实际上返回了它所做的更改次数。因此,最后额外的 $_ 导致 perl 返回 @outdata 的每个元素的修改后的字符串。
Greg 的答案有一个问题,即它会修改原始数组,因为 $_ 是通过别名传递的。你需要:
@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;
为了跟进 Tithonium 的观点,这也可以解决问题:
@filtered = map {local $_=$_; s/ //g; $_} @outdata;
“本地”确保您正在处理副本,而不是原件。
在 perl 5.14 中,您可以使用/r正则表达式修饰符进行非破坏性替换。
@filtered = map {s/ //gr} @outdata;
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;
作为 Greg 答案的对立面,您可能会误用 grep:
@filtered = grep {s/ //g; 1} @outdata;
不要这样做。