使用Perl将数据转换为数组

时间:2012-11-03 17:03:53

标签: perl

如何使用Perl将数据转换为数组?

这是我的数据:

my $data =
  "203.174.38.128203.174.38.129203.174.38.1" .
  "30203.174.38.131203.174.38.132203.174.38" .
  ".133203.174.38.134173.174.38.135203.174." .
  "38.136203.174.38.137203.174.38.142";

我想把它变成像这样的数组

my @array= (
  "203.174.38.128",
  "203.174.38.129",
  "203.174.38.130",
  "203.174.38.131",
  "203.174.38.132",
  "203.174.38.133",
  "203.174.38.134",
  "173.174.38.135",
  "203.174.38.136",
  "203.174.38.137",
  "203.174.38.142"
);

任何人都知道如何使用Perl做到这一点?

3 个答案:

答案 0 :(得分:1)

如果记录的IP的第一部分始终是203,那就很容易:

my @arr = split /(?<=\d)(?=203\.)/, $data;

在给出的示例中,它不是,但第一部分总是3位数,第二部分总是174,所以它足以做...

my @arr = split /(?<=\d)(?=\d{3}\.174\.)/, $data;

...以获得正确的结果。

但请理解,在这里提供更通用(和防弹)的解决方案几乎是不可能的 - 当这些'标记'部分是......太动态了。例如,取这个字符串......

11.11.11.22222.11.11.11

问题是,在哪里拆分?它应该是11.11.11.22; 222.11.11.11吗?还是11.11.11.222; 22.11.11.11?如果你问我,两者都是非常有效的IP。试图分裂'2222'部分(可能是'2; 222','22; 22'甚至'222; 2')可能会变得更糟。

例如,你可以制定一个规则:“将每个序列的> 3个数字后跟一个点符号分开,这样这个分割的第二个部分总是从3个数字开始”:

my @arr = split /(?<=\d)(?=\d{3}\.)/, $data;

...但是如果您的数据字符串中存在两个甚至一位数的第一个八位字节的IP,这显然无法在前面提到的模糊情况下正常工作。

答案 1 :(得分:1)

如果您编写的正则表达式将匹配四重奏中某个数字的任何有效值,那么您可以只搜索它们并以四个为一组重新组合它们。此

/2[0-5][0-5]|1\d\d|[1-9]\d|\d/

匹配200-255或100-199或10-99或0-9,使用它的程序如下所示。

如果有多种方法可以分割字符串,则无法知道要采用哪个选项,此解决方案会将最长的值分配给两个IP地址中的第一个。例如,1.1.1.1234.1.1.1将分为1.1.1.1234.1.1.1

use strict;
use warnings;

use feature 'say';

my $data =
  "203.174.38.128203.174.38.129203.174.38.1" .
  "30203.174.38.131203.174.38.132203.174.38" .
  ".133203.174.38.134173.174.38.135203.174." .
  "38.136203.174.38.137203.174.38.142";

my $byte = qr/2[0-5][0-5]|1\d\d|\d\d|\d/;

my @bytes = $data =~ /($byte)/g;
my @addresses;
push @addresses, join('.', splice(@bytes, 0, 4)) while @bytes;

say for @addresses;

<强>输出

203.174.38.128
203.174.38.129
203.174.38.130
203.174.38.131
203.174.38.132
203.174.38.133
203.174.38.134
173.174.38.135
203.174.38.136
203.174.38.137
203.174.38.142

答案 2 :(得分:0)

使用您的示例,看起来您的第一个和最后一个节点有3位数字。这会提示使用这种模式:

/(\d{3}\.\d{1,3}\.\d{1,3}\.\d{3})/

使用/g开关添加它,它将拉动每一个。

但是,如果您拥有的数据集大于您为示例显示的数据,则有人应该在将转储到此字符串之前将ips 分开。如果它们是单独的数据点,则它们应该具有一些分离