表达式捕获组的问题
Issue with a expression capturing groups
我有一些这样的数据
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})
如有任何帮助,我们将不胜感激。
这是当前正则表达式的图像
你快到了。您只需要在 eth
之后添加 .*?
以便它匹配 eth
和 ip 地址之间的字符。
^(.*?)eth.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
如果您不希望 eth
之前的 space 不被第 1 组捕获,那么您可以像这样更改您的正则表达式,
^(.*?)\s+eth.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
有时,人们会忽略点分十进制 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)/;
我有一些这样的数据
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})
如有任何帮助,我们将不胜感激。
这是当前正则表达式的图像
你快到了。您只需要在 eth
之后添加 .*?
以便它匹配 eth
和 ip 地址之间的字符。
^(.*?)eth.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
如果您不希望 eth
之前的 space 不被第 1 组捕获,那么您可以像这样更改您的正则表达式,
^(.*?)\s+eth.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
有时,人们会忽略点分十进制 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)/;