0

如何使用 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 做到这一点吗?

4

3 回答 3

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,那么在前面提到的模棱两可的情况下,这显然无法正常工作。

于 2012-11-03T17:06:42.217 回答
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
于 2012-11-03T23:37:31.647 回答
0

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

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

加上一个/g开关,它会拉动每一个。

但是,如果您的数据集比您为样本显示的数据集更大且不同,则应该有人在将 ips转储到此字符串之前将它们分开。如果它们是单独的数据点,它们应该有一些分离

于 2012-11-03T18:29:38.063 回答