Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 表达式捕获组时出现问题_Regex_Perl_Expression_Capture - Fatal编程技术网

Regex 表达式捕获组时出现问题

Regex 表达式捕获组时出现问题,regex,perl,expression,capture,Regex,Perl,Expression,Capture,我有一些这样的数据 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 20

我有一些这样的数据

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})

如果您不希望组1不捕获
eth
之前的空格,则可以这样更改正则表达式

^(.*?)\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)/;

我不得不等了8分钟