2012-11-22 68 views
3

我正在寫一個日誌分析器,它讀取日誌行由行,我有大約100規則,它的工作原理是這樣的:加快正則表達式匹配?

if ($line =~ /blabla (field1) (field2)/) 
{ do something } 
else if ($line =~ /something (field1) (field2) else/) 
{ do something } 

但對於一個大的日誌文件,它可能會很慢匹配這麼多規則的一條線,它會是O(n)

那麼,對這個問題有什麼建議嗎?由於它不僅僅是簡單的字符串和通配符匹配,我不知道是否有任何數據結構可以使用。

+0

你介意給我們一些你的數據樣本嗎?而另一個問題是,這裏允許使用哪種語言? – Rubens

+0

@Rubens你好,rubens,你的意思是「任何語言」?你的意思是如果我可以接受另一種編程語言? – daisy

+0

是的,對不起,這正是問題:它可以用任何語言製作嗎?只是注意到有一個標籤指的是perl ^^無論如何,你能得到一些兩三行的數據,還是僅僅是一個帶有主分隔符的例子? – Rubens

回答

1

我建議你重新設計你的日誌解析器。可能是我錯了,但我想你會嘗試匹配可能發生在日誌文件中的所有情況。

嘗試使用詞法和句法分析器。對不起,我不知道Perl上的好樣本,但類似Parse::Yapp

5

我相信你的優化還爲時過早。

你用這個名義上的大日誌文件試過嗎?它實際上太慢了嗎?然後,如果它實際上太慢,請使用諸如Devel :: NYTProf之類的分析工具來查明確切的速度正在變慢。

+1

感謝您解決正則表達式和正則表達式匹配問題。基準測試顯示,使用正則表達式比使用正則表達式對象快37%。已刪除我的回覆。爲您的Devel :: NYTProf建議+1。 – Kenosis

6

也許可以使用調度表?

my %handlers = (
    blabla => \&blabla, 
    something => \&something, 
); 

while (<>) { 
    my ($keyword) = $line =~ /^(\S+)/ 
     or next; 

    $handlers{$keyword} 
     or next; 

    $handlers{$keyword}->($line); 
} 
1

您可以將多個正則表達式組合成一個單一的一個使用Regexp::Assemble

下面是從模塊

正則表達式::組裝的描述,以加快比賽需要定期任意數量表達式並將它們組裝成單個正則表達式(或RE),以匹配單個RE匹配的所有單個正則表達式。

因此,不需要大量的表達式循環,只需要針對一個表達式測試目標字符串。當你有幾千種模式需要處理時,這很有趣。認真努力製作出儘可能小的圖案。

也可以跟蹤原始模式,以便確定組成模式的源模式中哪一個是導致匹配發生的模式。