perl IP范围操作

perl IP范围操作

费了九牛二虎之力,用per取得了 电信IP段,但发现有很多包含部分如下:请问如何去掉包含部分,即取得最大范围的IP端.



58.32.0.0 - 58.41.255.255
58.32.0.0 - 58.32.7.255
58.32.8.0 - 58.32.11.255
58.32.12.0 - 58.32.15.255
...............................
58.42.0.0 - 58.42.255.255
58.43.0.0 - 58.43.255.255
58.44.0.0 - 58.47.255.255

如以上部分,可以归为
l58.32.0.0 - 58.47.255.255


请问用PERL如何做到?谢谢各位!
1. 对开始IP&结束IP按数字排序.
2. 每次读一个待合并网段, 只需与处理后的最后一个网段进行比较, 判断是可合并的, 还是新网段.
有一个建议,先把IP处理成下面的形式:
比如:58.32.0.0
变成:058032000000
IP变成了数,就可以直接比较大小.方便后面的操作

最后再变回来
比如这段代码可以把IP译成数的形式
[code]
@aa=sort split/\n/,"
58.32.0.0 - 58.41.255.255
58.32.0.0 - 58.32.7.255
58.32.8.0 - 58.32.11.255
58.32.12.0 - 58.32.15.255
58.42.0.0 - 58.42.255.255
58.43.0.0 - 58.43.255.255
58.44.0.0 - 58.47.255.255
";

#print "$_\n" for @aa;
foreach(@aa) { print map{s/ //;$_="000000".$_;s/.*(\d\d\d$)/\1/;$_}split/[-.]/,$_;print "\n";}

#输出为:
058032000000058032007255
058032000000058041255255
058032012000058032015255
058032008000058032011255
058042000000058042255255
058043000000058043255255
058044000000058047255255
[\code]


QUOTE:
原帖由 crazidog 于 2007-12-5 23:32 发表
有一个建议,先把IP处理成下面的形式:
比如:58.32.0.0
变成:058032000000
IP变成了数,就可以直接比较大小.方便后面的操作

最后再变回来

#转成数字固然可行, 但转换回来较麻烦.
#既然都+0填充了, 何不按字母比较:

my @ip_raw = (
    '58.32.0.0 - 58.41.255.255',
    '58.32.0.0 - 58.32.7.255',
    '58.32.8.0 - 58.32.11.255',
    '58.32.12.0 - 58.32.15.255',
    '58.42.0.0 - 58.42.255.255',
    '58.43.0.0 - 58.43.255.255',
    '58.44.0.0 - 58.47.255.255',
);

my @ip_sort = sort sort_by_ip @ip_raw;
print join("\n", @ip_sort);

sub sort_by_ip {
    my ($aa, $bb) = ($a, $b);
    $aa =~ s/(\d+)/sprintf("%03s", $1)/eg;
    $bb =~ s/(\d+)/sprintf("%03s", $1)/eg;
    return ($aa cmp $bb);
}
楼上的程序不错,学到东东了,感谢!


QUOTE:
sub sort_by_ip {
    my ($aa, $bb) = ($a, $b);
    $aa =~ s/(\d+)/sprintf("%03s", $1)/eg;
    $bb =~ s/(\d+)/sprintf("%03s", $1)/eg;
    return ($aa cmp $bb);
}

另有两个问题:
1,楼上的楼上,发帖中代码的颜色怎么加的,很酷!!
2,上面这段程序,替换的那两句,有没有方法简写成一句,这个函数作为sort的排列方式,有没有更简洁的写法,谢谢!
1. 点下方的"回复帖子"按钮, 看到一个"C++"按钮, 下拉选Perl.

2. 首先, 我个人不太赞成一行很长, 那样会给别人造成阅读障碍, 也很难看.
    你若非要合并的话, 在sort前处理好数据, sort过程中就不用修改$a, $b,
    那么就可以去掉一个单独的callback函数, 而以sort { .... } LIST 来排序.
但是我的文件很大很大,以上只是一个例子。
请问具体如何操作呢?
如果文件真的很大很大, 那么可以平均分为几个部分, 对每个部分处理, 最后合并再做相同处理.

类似归并排序.