5

当我运行以下语句时:

@filtered = map {s/ //g} @outdata;

它返回一个空列表,而不是我期望的过滤列表。我要做的是 从字符串数组(这是一个 XML 文件)中删除每次出现的 。

显然,我不明白一些事情。谁能告诉我这样做的正确方法可能是,为什么这对我不起作用?

4

7 回答 7

15

请注意, map 也将修改您的源数组。所以你可以这样做:

map {s/ //g} @outdata;

并完全跳过 @filtered 变量,或者如果您需要保留原件,

@filtered = @outdata;
map {s/ //g} @filtered;

虽然在这种情况下,使用 foreach 可能更具可读性:

s/ //g foreach @filtered;
于 2008-08-22T04:51:03.680 回答
10

试试这个:

@filtered = map {s/ //g; $_} @outdata;

问题是 perl 中的 s 运算符修改了 $_ 但实际上返回了它所做的更改次数。因此,最后额外的 $_ 导致 perl 返回 @outdata 的每个元素的修改后的字符串。

于 2008-08-15T09:49:17.153 回答
9

Greg 的答案有一个问题,即它会修改原始数组,因为 $_ 是通过别名传递的。你需要:

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;
于 2008-09-15T14:18:34.320 回答
6

为了跟进 Tithonium 的观点,这也可以解决问题:

@filtered = map {local $_=$_; s/ //g; $_} @outdata;

“本地”确保您正在处理副本,而不是原件。

于 2008-09-15T14:04:43.807 回答
5

在 perl 5.14 中,您可以使用/r正则表达式修饰符进行非破坏性替换

@filtered = map {s/ //gr} @outdata;
于 2012-05-18T17:31:29.930 回答
4
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;
于 2008-12-01T03:35:43.613 回答
3

作为 Greg 答案的对立面,您可能会误用 grep:

@filtered = grep {s/ //g; 1} @outdata;

不要这样做。

于 2008-08-17T15:51:55.073 回答