2015-12-09 6 views
0

Я использовал http://www.regexe.com/ для проверки регулярного выражения, которое я создал, чтобы извлечь дату и время из syslog, и он показывает мне, что регулярное выражение на самом деле правильное, выделяя дату и время. Однако, когда я пытаюсь это сделать в Perl, я возвращаюсь с указанием времени, а не даты.Regex не полностью соответствует строке

так, например, из строки 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

Мэтт, это не работает, я попробовал это раньше. Я использую Kali Linux, если это имеет значение. – Simon

+0

Я только что тестировал [IDEONE и ваши регулярные выражения] (http://ideone.com/wduhGO). –

+0

stribizhev Чего я хочу достичь - это дата и время, а не только дата. – Simon

ответ

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}). Вы можете использовать этот последний вариант, поскольку он краток и читабельнее.

Там нет смысла в размещении : в символьный класс [:], двоеточие не должны быть экранированы в регулярных выражений шаблона (если это не регулярное выражение разделителем, а вот это не так).

+0

Рад, что это сработало для вас. Пожалуйста, также подумайте над тем, чтобы мой ответ оказался полезным для вас (см. [Как повысить уровень переполнения стека?] (Http://meta.stackexchange.com/questions/173399/how-to-upvote-on-stack-overflow)) так как теперь у вас есть привилегия. –

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

+0

Can not вы просто кладете группу вокруг всего регулярного выражения?Это не похоже на то, что OP заинтересован в разделении даты с момента времени – NullUserException

+0

Это действительно работает, однако я хотел бы сохранить дату и время как одно. – Simon

+0

Думаю, я просто без слов. – sln

Смежные вопросы