正则表达式与字符串

时间:2015-12-09 22:34:54

标签: regex perl pattern-matching

我已使用http://www.regexe.com/来测试我创建的正则表达式,以便从syslog中提取日期和时间,并且它向我显示正则表达式实际上是正确的,突出显示日期和时间。然而,当我在Perl中尝试这个时,我只是回来了,而不是日期。

所以例如来自字符串Dec 9 12:45:36 osboxes NetworkManager[739]: <info> address 192.168.10.129 我将被退回12:45:36

这是我的剧本:

use strict;
use warnings;

my $keywords = 'keywords.txt';
open(my $kw, '<:encoding(UTF-8)', $keywords)
or die "Could not open file '$keywords' $!";    # Open the file, throw an exception if the file cannot be opened. 
chomp (my @keywordsarray = <$kw>); # Remove whitespace, and read it into an array 
close($kw);# Close the file 

my $syslog = 'syslog';
open(my $sl, '<:encoding(UTF-8)', $syslog)
or die "Could not open file '$keywords' $!";    # Open the file, throw an exception if the file cannot be opened. 
chomp (my @syslogarray = <$sl>); # Remove whitespace, and read it into an array 
close($sl);# Close the file  

foreach my $line (@syslogarray) 
{
foreach my $keyword (@keywordsarray)
{
    if ($line =~ m/\Q$keyword\E/)
    {
        if ((my $date) = $line =~  m/[A-z]+\s{2}\d{1,}\s((\d{2}[:]){2}\d{2})/)
        {   
            print "**". $keyword. "**". $date. "\n";
        }
    }
}
}

2 个答案:

答案 0 :(得分:1)

您可以在整个模式周围使用捕获组。

if ((my $date) = $line =~  m/([A-Z]+\s{2}\d+\s(?:\d{2}:){2}\d{2})/i)
                             ^                                  ^

请参阅IDEONE demo

当您使用(my $date)时,您告诉引擎将第一个捕获组匹配的内容放入$date变量。因此,您只需要在模式的那部分周围使用一对未转义的括号,它们将匹配输入字符串中必要的文本字符串。

请注意,[A-z]含糊不清(请参阅[A-z] and [a-zA-Z] difference),最好使用[A-Za-z]修饰符重新编写为[A-Z]/i(正如我所建议的那样)上文)。

此外,\d{1,}等于\d++量词表示 1次或更多次出现,与{1,0}相同。您可以使用后一种变体,因为它简洁且更易读。

:放入字符类[:]没有意义,冒号不必以正则表达式模式进行转义(除非它是正则表达式分隔符,此处不是)

答案 1 :(得分:0)

您必须在日期周围放置一个小组 -

/(?i)([a-z]+\s{2}\d{1,})\s((?:\d{2}:){2}\d{2})/

格式化:

 (?i)
 ( [a-z]+ \s{2} \d{1,} )       # (1), Date
 \s 
 (                             # (2 start), Time
      (?: \d{2} : ){2}
      \d{2} 
 )                             # (2 end)

然后,在列表中添加另一个变量。

if (($date, $time) = $line =~ /([A-z]+\s{2}\d{1,})\s((?:\d{2}:){2}\d{2})/)