我有一些像这样的数据
Wed Mar 18 15:16:10 2015 eth0:1 109.224.232.219 up (not currently mapped)
Wed Mar 18 15:18:12 2015 eth0:1 109.224.232.219 down (not responding)
Wed Mar 18 15:20:46 2015 eth0:1 109.224.232.219 up (not currently mapped)
Wed Mar 18 15:22:52 2015 eth0:1 109.224.232.219 down (not responding)
Wed Mar 18 15:24:26 2015 eth0:1 109.224.232.219 up (not currently mapped)
我正在尝试捕获每行上的IP和日期字符串,我以为我可以在单词eth之前做任何事情然后我的IP检查,但这不起作用。我是否误解了捕获组的概念?
是否有一种合理的方法可以从1个正则表达式获取此数据?
(^(.*?)eth)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
任何帮助都将不胜感激。
这是当前正则表达式的图像
答案 0 :(得分:0)
你几乎就在那里。您只需在.*?
之后添加eth
,以便它与eth
和ip-address之间的字符匹配。
^(.*?)eth.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
如果您不希望第1组无法捕获eth
之前的空格,那么您可以像这样更改正则表达式,
^(.*?)\s+eth.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
答案 1 :(得分:-1)
有时,人们会忽略点分十进制IP表示的明确定义的字符序列。当我完全详细说明一个合适的IP八位字节时,我几乎没有没有问题来识别IP。
my $octet = qr/\b(?:0|1\d{0,2}|2(?:[0-4]\d?|5[0-5]?|[6-9])?|[3-9]\d?)\b/;
my ( $foctet = "$octet" ) =~ s/0[|]//;
然后,最重要的是,我指定一个IP地址是一组四个八位字节,用点分隔。
my $ip_regex = qr/($foctet(\.$octet){3})/;
这个小小的美女几乎总能从任何文件中获取任何有效IP。
除此之外,还可以使用更高的规格指定日期。再次,按照这个规范,你得到的将几乎不可避免地是一个日期:
my $dow = qr/\b(?:Fri|Mon|Sat|Sun|Thu|Tue|Wed)\b/;
my $mon = qr/\b(?:Apr|Aug|Dec|Feb|Jan|Jul|Jun|Mar|May|Nov|Oct|Sep)\b/;
my $day = qr/\b(?:[012]\d?|3[01]?|[4-9])\b/;
my $hr24 = qr/\b(?:[01]\d?|2[0-3])\b/;
my $minsec = qr/\b(?:[0-5]\d)\b/;
my $datetime_regex = qr/$dow\s+$mon\s+$day\s+$hr24:$minsec:$minsec\s+\d+/;
因此,只需对源代码行使用两个正则表达式,即可获得所需的内容,而无需进行大量的回溯。
my @date_parts = $line =~ /$datetime_regex/;
my ( $ip ) = $line =~ /$ip_regex/;
事实上,如果性能是一个问题,我看到单个正则表达式中有很多失败与非贪婪的匹配,而ip正则表达式首次尝试成功。正则表达式引擎找到了'。'在偏移35处并从位置32开始。
然而,以下情况并非一次都失败。只是表明它如何帮助您将表达式指定到预期的数据范围:
my ( $dt, $ip ) = m/($datetime_regex)\s+eth\d:\d+\s+($ip_regex)/;