当我有空格或中间回车时匹配IP地址

时间:2014-03-15 14:16:27

标签: regex perl

我正在使用Perl脚本,用户从命令行运行tracert并从cli复制并在perl CGI脚本中提交tracert&我的脚本将tracert保存为文件。

然后我一次打开一行文件并通过Perl Regex grep获取ip地址。

问题是:有时用户跟踪某些跳跃的结果变得太大,下面是一个示例,IP地址分为两部分(使用CR& LF),因此我的正则表达式匹配失败。

4 2 ms 1 ms 1 ms routers.static-ABC.XYZ.net.in [165

.112.109.61]

我正在寻找一些解决方案,要么我可以移除文件的所有白色和其他空间,要么得到一个我可以匹配的正则表达式和中间的IP地址(使用CR& LF)两行。

如果我能以某种方式让我的程序搜索"]"在文件中,如果我找不到这个,并且在行的末尾有一个空格(CR& LF),则删除空格并加入该行。这将解决我的问题。

以下是脚本的一部分:

my @array;
open(my $fh, "<", "trace.txt")
or die "Failed to open file: $!\n";


while(<$fh>) { 

    &match_ip($_);  ##match_ip(@array);

} 
close $fh;

sub match_ip()
{       

    if($_ =~ m/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/g)
    {
        $ip = "$1\.$2\.$3\.$4";
        print "$ip\n";
    }
}

5 个答案:

答案 0 :(得分:1)

它只发生在点上吗?在这种情况下,你可以这样做:

if($_ =~ m/([0-9]{1,3})\s*\.\s*([0-9]{1,3})\s*\.\s*([0-9]{1,3})\s*\.\s*([0-9]{1,3})/g)
{
    $ip = "$1\.$2\.$3\.$4";
    print "$ip\n";
}

或者,你也可以研究IP出现在方括号之间的事实(如果是这种情况就像你展示的那样;如果没有,你仍然可以这样做,但最后过滤掉非IP):

$_ =~ /\[(.*?\s*?.*?)\]/;  # extract everything between square brackets
my $ip = $1;     # take that IP
$ip =~ s/\s//g; # remove possible white spaces from the IP

答案 1 :(得分:0)

如果您逐行循环遍历文件并且IP分为两行,则所提议的正则表达式解决方案都不起作用。您可以在段落模式下读取数据,在这种情况下,所有跃点都将在一个字符串中。

就个人而言,我可能会以不同的方式看待这一点。我将这条线拆分成一个数组。 Windows tracert命令为每个跃点使用8到9个字段。如果数组少于8个字段,那么行是&#34;包裹&#34;并且应该在解析IP之前添加到上一行。这种方法需要您一次处理2行,以确定换行并将行重新连接在一起。

答案 2 :(得分:0)

逐行解决方案:

#!/usr/bin/perl

use strict;
use warnings;

while(<DATA>) {
    if (/(\d+(?:\.\d+){3})]$/) { 
        print $1 . "\n";
    } else {
        my $tmp;
        if (/\[([\d.]+)$/) {
            $tmp = $1;
        } else { next; }
        while(<DATA>) {
            if (/([\d.]+)]$/) {
                $tmp .= $1;
                print $tmp . "\n";
                last;
            } elsif (/([\d.]+)$/) {
                $tmp .= $1;
            }
        }
    }
}


__DATA__
 1    24 ms    22 ms    22 ms  1.32.202.62.cust.bluewin.ch [62.202.32.1]
 2    22 ms    24 ms    22 ms  1.32.202.62.cust.bluewin.ch [62.202.32.1]
 3    24 ms    23 ms    22 ms  net481.bwrt2zhb.bluewin.ch [195.186

 .121.1]
 4   314 ms   162 ms    22 ms  net125.bwrt1inb.bluewin.ch [195.186.125.71]
 5    34 ms    23 ms    24 ms  if114.ip-plus.bluewin.ch [195.186.0.114]
 6    27 ms    29 ms    29 ms  i68geb-005-gig4-2.bb.ip-plus.net [138.1

 87.1

 30.158]
 7    39 ms    39 ms    38 ms  i00par-005-pos4-0.bb.ip-plus.net [138.187.129.34]
 8    38 ms   320 ms    39 ms  feth2-kara-ielo.freeix.net [213.228.3.203]
 9   284 ms    39 ms    39 ms  feth0-bestelle.tlcy.fr.core.ielo.net [212.85.144.6]
10    90 ms   158 ms    83 ms  chloe.wikimedia.org [212.85.150.132] 

答案 3 :(得分:0)

由于它是一个小文件,因此请考虑在整个文件中进行啜食,全局捕获[]之间的所有IP,然后删除这些捕获中的任何空格。下面的子例程getIPsFromFile执行此操作:

use strict;
use warnings;

my @IPs = getIPsFromFile('trace.txt');

print "$_\n" for @IPs;

sub getIPsFromFile {
    my ($file) = @_;

    my $contents = do {
        local $/;
        open my $fh, '<', $file or die $!;
        <$fh>;
    };

    return map { s/\s+//g; $_ } $contents =~ /\[(.+?)\]/gs;
}

希望这有帮助!

答案 4 :(得分:0)

似乎每个跃点的tracert输出始终以间距开头,后跟跳数,后跟更多间距。即使有包装,也可以用它来表示跳跃的开始,因为没有包裹将有一个由间距包裹的数字。

在该行的另一端,ip地址将是最后一个条目,它可能会也可能不会被括号[]括起来。此外,ip实际上可能只是说“请求超时”。

鉴于此信息,我构建了适用于ipv4和ipv6数据的脚本:

use strict;
use warnings;

my $hop = '';

while (<DATA>) {
    chomp;

    # Start or End of new hop
    if ((my $startHop = $_ =~ /^\s+\d+\s+/) || /Trace complete./) {
        if ($hop =~ /^\s+(\d+).*\s\[?(\S+?)\]?$/) {
            print "IP = $1 - $2\n";
        }

        $hop = $startHop ? $_ : '';
    } elsif ($hop) {
        $hop .= $_;
    }
}

if ($hop =~ /^\s+(\d+).*\s\[?(\S+?)\]?$/) {
    print "IP = $1 - $2\n";
}

__DATA__
Tracing route to ds-any-fp3-real.wa1.b.yahoo.com [98.138.253.109]
over a maximum of 30 hops:

  1     3 ms     1 ms     1 ms  READYSHARE [192.168.1.1]
  2    33 ms    27 ms    29 ms  c-67-164-32-1.hsd1.ca.comcast.net [67.164.32.1]

  3    16 ms    11 ms    10 ms  te-7-6-ur02.oakland.ca.sfba.comcast.net [68.85.2
17.169]
  4    13 ms    12 ms    11 ms  te-0-2-0-6-ar01.oakland.ca.sfba.comcast.net [68.
87.194.230]
  5    13 ms    15 ms    21 ms  be-100-ar01.sfsutro.ca.sfba.comcast.net [68.85.1
55.18]
  6    22 ms    31 ms    24 ms  he-3-8-0-0-cr01.sanjose.ca.ibone.comcast.net [68
.86.94.85]
  7    25 ms    23 ms    23 ms  50.242.148.34
  8    86 ms    87 ms    86 ms  vlan90.csw4.SanJose1.Level3.net [4.69.152.254]
  9   111 ms    92 ms    84 ms  ae-92-92.ebr2.SanJose1.Level3.net [4.69.153.29]

 10   118 ms    85 ms    86 ms  ae-3-3.ebr1.Denver1.Level3.net [4.69.132.58]
 11    89 ms   262 ms    85 ms  ae-1-100.ebr2.Denver1.Level3.net [4.69.151.182]

 12    88 ms    92 ms    86 ms  ae-3-3.ebr1.Chicago2.Level3.net [4.69.132.62]
 13    87 ms    91 ms    88 ms  ae-1-51.edge3.Chicago3.Level3.net [4.69.138.136]

 14    92 ms    87 ms   115 ms  YAHOO-INC.edge3.Chicago3.Level3.net [4.53.96.158
]
 15   105 ms   102 ms   104 ms  ae-7.pat1.nez.yahoo.com [216.115.104.124]
 16   117 ms   120 ms   101 ms  ae-1.msr1.ne1.yahoo.com [216.115.100.5]
 17   177 ms   103 ms   108 ms  xe-7-0-0.clr2-a-gdc.ne1.yahoo.com [98.138.0.27]

 18   104 ms   104 ms   103 ms  et-18-25.fab7-1-gdc.ne1.yahoo.com [98.138.93.11]

 19   112 ms   104 ms   104 ms  po-16.bas2-7-prd.ne1.yahoo.com [98.138.240.34]
 20   104 ms   185 ms   114 ms  ir1.fp.vip.ne1.yahoo.com [98.138.253.109]

Trace complete.
##########
Tracing route to www.google.com [2607:f8b0:4003:c06::68]
over a maximum of 30 hops:

  1   466 ms   311 ms   132 ms  dsldevice6.att.net [2602:301:7766:d3a0:5ccc:b9ff
:fedb:9ea0]
  2   275 ms     *      240 ms  2602:300:c533:1510::6
  3   101 ms   469 ms   254 ms  sj2ca405me3.ipv6.att.net [2001:1890:ff:ffff:12:1
22:119:193]
  4     *        *        *     Request timed out.
  5    93 ms    45 ms    59 ms  2001:4860::1:0:7ea
  6   363 ms    72 ms    53 ms  2001:4860::8:0:6117
  7   292 ms   224 ms   189 ms  2001:4860::8:0:3427
  8    99 ms    77 ms     *     2001:4860::8:0:2c9d
  9   251 ms   167 ms   246 ms  2001:4860::8:0:64c7
 10   196 ms   274 ms   248 ms  2001:4860::2:0:5bab
 11     *        *        *     Request timed out.
 12   270 ms   202 ms   362 ms  2607:f8b0:4003:c06::68

输出

IP = 1 - 192.168.1.1
IP = 2 - 67.164.32.1
IP = 3 - 68.85.217.169
IP = 4 - 68.87.194.230
IP = 5 - 68.85.155.18
IP = 6 - 68.86.94.85
IP = 7 - 50.242.148.34
IP = 8 - 4.69.152.254
IP = 9 - 4.69.153.29
IP = 10 - 4.69.132.58
IP = 11 - 4.69.151.182
IP = 12 - 4.69.132.62
IP = 13 - 4.69.138.136
IP = 14 - 4.53.96.158
IP = 15 - 216.115.104.124
IP = 16 - 216.115.100.5
IP = 17 - 98.138.0.27
IP = 18 - 98.138.93.11
IP = 19 - 98.138.240.34
IP = 20 - 98.138.253.109
IP = 1 - 2602:301:7766:d3a0:5ccc:b9ff:fedb:9ea0
IP = 2 - 2602:300:c533:1510::6
IP = 3 - 2001:1890:ff:ffff:12:122:119:193
IP = 4 - out.
IP = 5 - 2001:4860::1:0:7ea
IP = 6 - 2001:4860::8:0:6117
IP = 7 - 2001:4860::8:0:3427
IP = 8 - 2001:4860::8:0:2c9d
IP = 9 - 2001:4860::8:0:64c7
IP = 10 - 2001:4860::2:0:5bab
IP = 11 - out.
IP = 12 - 2607:f8b0:4003:c06::68

注意,偶尔ip显示为“out”。这是因为请求超时了。