2015-12-09 53 views
0

我已使用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

馬特,這不工作,或者我早些時候嘗試過。如果這有什麼不同,我使用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

很高興爲你效勞。如果我的回答對你有幫助,請考慮upvoting(參見[如何在堆棧溢出?](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