我已使用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";
}
}
}
}
答案 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})/)