如何在perl中使用这个map运算符?

时间:2014-11-21 10:50:19

标签: regex perl map

我对regexp中的地图运算符感到困惑。

我的剧本

use warnings;
use strict;
my @ar = map{~s/da//g} <DATA>;
print "@ar\n";

__DATA__
da

在此程序中,在版本5.16.2或5.14.2上执行,输出为4294967294,但在该版本5.18.2上运行的程序中,输出为18446744073709551614

我在修改数据值,如

__DATA__
da
da da 
da da da da
da da da da da 

版本5.18.2中的此输出

18446744073709551614 18446744073709551613 18446744073709551611 18446744073709551610

版本5.16.2或5.14.2中的输出

4294967294 4294967293 4294967291 4294967290

输入数据减少的最后一个数字与发生匹配。

实际上我并没有因为任何问题而尝试这个。我希望

1)输出中数字的含义是什么?

2)为什么每个版本的输出都会发生变化(v5.18.2,v5.16.2)?

2 个答案:

答案 0 :(得分:2)

替换不返回已更改的字符串,它返回替换次数。 ~是按位否定,所以你看到的等价于~1,它在32位和64位Perls上是不同的。

比较

say for ~1, unpack "Q", pack "B*", 1 x 64;

可以实现您的目标
map { s/da//gr } <DATA>;

在Perl 5.14及更新版本中,对于旧版本,您无法使用/r,因此您必须解决它:

map { s/da//g; $_ } <DATA>;

答案 1 :(得分:2)

choroba已经给出了答案。我想出了这个可视化来帮助显示正在发生的事情。由于我们使用按位否定,因此以位为单位显示数字是合乎逻辑的,换句话说,以二进制形式打印数字:

<强>代码:

use strict;
use warnings;

printf "%064b\n%064b\n-=-\n", $_, ~ $_ for 1 .. 4;

<强>输出:

0000000000000000000000000000000000000000000000000000000000000001
1111111111111111111111111111111111111111111111111111111111111110
-=-
0000000000000000000000000000000000000000000000000000000000000010
1111111111111111111111111111111111111111111111111111111111111101
-=-
0000000000000000000000000000000000000000000000000000000000000011
1111111111111111111111111111111111111111111111111111111111111100
-=-
0000000000000000000000000000000000000000000000000000000000000100
1111111111111111111111111111111111111111111111111111111111111011
-=-

在这里很容易看到数字1(由000000....1表示)从其按位否定的末尾删除,数字102的二进制数从其按位否定结束时删除,等等。

在您的情况下,替代的使用与结果无关。重要的是它会生成一个数字。