Regex 从一行中检测特定文本并将其保存在数组中

Regex 从一行中检测特定文本并将其保存在数组中,regex,perl,csv,text,Regex,Perl,Csv,Text,我有一个文本文件,它由不同的行组成 Destination|203.190.242.69|reached|203.190.244.6 Destination|208.109.249.198|reached|212.142.1.1 Destination|94.75.253.170|reached|85.17.100.90 Destination|212.112.234.228|reached|4.69.143.210 Destination|80.146.246.42|reached|192.1

我有一个文本文件,它由不同的行组成

Destination|203.190.242.69|reached|203.190.244.6
Destination|208.109.249.198|reached|212.142.1.1
Destination|94.75.253.170|reached|85.17.100.90
Destination|212.112.234.228|reached|4.69.143.210
Destination|80.146.246.42|reached|192.168.1.1
Destination|122.209.193.217|reached|59.128.3.65
Destination|66.77.197.179|reached|66.77.197.251
Destination|195.254.227.65|reached|213.21.128.141
Destination|125.208.8.253|reached|125.208.15.254
我需要保存这两个IP并将它们保存在不同的阵列中。所以会有 可以是两个阵列,一个目标,一个到达。我怎样才能做到这一点。目前,我已经编写了一个代码来检测IP,但这似乎不起作用

while (my $line = <$in>) {
    my $traceroute;
    if ($line =~ /(^Destination)/) {
        print "DUDE\n";
        my $ip = $line =~ /(\d+\.\d+\.\d+\.\d+)$/s;
        #$traceroute = $2;
        print "$ip\n";
    }
}

在分隔符上拆分并保存索引1和3处的项目

perl -aF'\|' -lne 'next unless $F[0] eq "Destination"; print "$F[1]|$F[3]"' input >output

当然,您可能需要不同的输出格式和/或执行更多操作。

在分隔符上拆分,并将项目保存在索引1和3处

perl -aF'\|' -lne 'next unless $F[0] eq "Destination"; print "$F[1]|$F[3]"' input >output

当然,您可能需要不同的输出格式和/或执行更多操作。

这应该可以做到:

while (my $line = <DATA>) {
    if($line =~ /(^Destination)/){
        my($dest, $reach) = $line =~ /(\d+\.\d+\.\d+\.\d+)/g;
        print "$dest $reach\n";
    }
}

__DATA__
Destination|203.190.242.69|reached|203.190.244.6
Destination|208.109.249.198|reached|212.142.1.1
Destination|94.75.253.170|reached|85.17.100.90
Destination|212.112.234.228|reached|4.69.143.210
Destination|80.146.246.42|reached|192.168.1.1
Destination|122.209.193.217|reached|59.128.3.65
Destination|66.77.197.179|reached|66.77.197.251
Destination|195.254.227.65|reached|213.21.128.141
Destination|125.208.8.253|reached|125.208.15.254
在标量上下文中执行正则表达式时,只返回成功匹配的数量,如果失败,则返回0。将正则表达式的结果赋给数组或变量列表会将其置于列表上下文中,正则表达式在其中返回捕获的值。
/g修饰符不仅匹配正则表达式一次,而且匹配频率与它在字符串中的匹配频率相同。阅读更多信息

这应该可以做到:

while (my $line = <DATA>) {
    if($line =~ /(^Destination)/){
        my($dest, $reach) = $line =~ /(\d+\.\d+\.\d+\.\d+)/g;
        print "$dest $reach\n";
    }
}

__DATA__
Destination|203.190.242.69|reached|203.190.244.6
Destination|208.109.249.198|reached|212.142.1.1
Destination|94.75.253.170|reached|85.17.100.90
Destination|212.112.234.228|reached|4.69.143.210
Destination|80.146.246.42|reached|192.168.1.1
Destination|122.209.193.217|reached|59.128.3.65
Destination|66.77.197.179|reached|66.77.197.251
Destination|195.254.227.65|reached|213.21.128.141
Destination|125.208.8.253|reached|125.208.15.254
在标量上下文中执行正则表达式时,只返回成功匹配的数量,如果失败,则返回0。将正则表达式的结果赋给数组或变量列表会将其置于列表上下文中,正则表达式在其中返回捕获的值。
/g修饰符不仅匹配正则表达式一次,而且匹配频率与它在字符串中的匹配频率相同。更多信息请阅读

,因为您希望将地址保存在数组中,而以前的解决方案都没有明确做到这一点,所以我发布另一个答案:

use strict;

my (@destination, @reached);
foreach my $line (<DATA>) {
    chomp $line;
    my @fields = split '\|', $line;
    push @destination, $fields[1];
    push @reached, $fields[3];
}

use Data::Dumper;
print "Destinations:\n".Dumper(@destination);
print "Reached:\n".Dumper(@reached);

__DATA__
Destination|203.190.242.69|reached|203.190.244.6
Destination|208.109.249.198|reached|212.142.1.1
Destination|94.75.253.170|reached|85.17.100.90
Destination|212.112.234.228|reached|4.69.143.210
Destination|80.146.246.42|reached|192.168.1.1
Destination|122.209.193.217|reached|59.128.3.65
Destination|66.77.197.179|reached|66.77.197.251
Destination|195.254.227.65|reached|213.21.128.141
Destination|125.208.8.253|reached|125.208.15.254

由于您希望将地址保存在数组中,而以前的解决方案都没有明确做到这一点,因此我发布了另一个答案:

use strict;

my (@destination, @reached);
foreach my $line (<DATA>) {
    chomp $line;
    my @fields = split '\|', $line;
    push @destination, $fields[1];
    push @reached, $fields[3];
}

use Data::Dumper;
print "Destinations:\n".Dumper(@destination);
print "Reached:\n".Dumper(@reached);

__DATA__
Destination|203.190.242.69|reached|203.190.244.6
Destination|208.109.249.198|reached|212.142.1.1
Destination|94.75.253.170|reached|85.17.100.90
Destination|212.112.234.228|reached|4.69.143.210
Destination|80.146.246.42|reached|192.168.1.1
Destination|122.209.193.217|reached|59.128.3.65
Destination|66.77.197.179|reached|66.77.197.251
Destination|195.254.227.65|reached|213.21.128.141
Destination|125.208.8.253|reached|125.208.15.254

打印DUDE的算法意义是什么哈哈,我只是想看看我的程序是否达到了目的:打印DUDE的算法意义是什么哈哈,只是为了检查我的程序是否达到了目的:pI很抱歉,我的问题是如何比较这两个IP,看看前三个八位组是否相似,例如,在第一行数据中,前两个八位组是相似的i很抱歉,我的问题是如何比较这两个IP,看看前三个八位组是否相似,在第一行数据中,前两个八位字节是相似的,这不是你所要求的。如果您在其他问题上需要帮助,那么我建议您发布一个新问题。那么,如果我只做$dest,$reach=$line=~/\d+\.\d+\.\d+\.\d+/g;然后push@destination,$dest;push@reached,$reach;这应该行吗?我写了以下内容,但似乎不起作用-当我的$line={if$line=~/^Destination/{my$dest,$reach=$line=~/\d+\.\d+\.\d+/g;push@destination,$dest;push@reached,$reach;}}}这不是你要的。如果您在其他问题上需要帮助,那么我建议您发布一个新问题。那么,如果我只做$dest,$reach=$line=~/\d+\.\d+\.\d+\.\d+/g;然后push@destination,$dest;push@reached,$reach;这应该行吗?我写了以下内容,但似乎不起作用-当我的$line={if$line=~/^Destination/{my$dest,$reach=$line=~/\d+\.\d+\.\d+/g;push@destination,$dest;push@reached,$reach;}}}您需要转义管道字符:\\您需要转义管道字符:\|