2012-02-18 33 views
2

這是that question的後續行爲。我已經瞭解到,在Python中找到重疊的正則表達式並不是直截了當的,因此決定進行一次額外的調查,以瞭解Perl和Ruby如何應對這一任務。在Perl或Ruby中計數重疊的正則表達式匹配

我想count正則表達式對特定字符串的所有可能匹配的數量。而「全部」我的意思是結果應該考慮到重疊和非唯一匹配。下面是一些例子:

  • a.*k應該兩次在"akka"
  • "bbboob"針對b.*o.*b測試匹配應該產生6

作爲參考,這裏是由tchrist建議一個Perl一行程序 - 它輸出正確的匹配和他們的計數:

() = "bbboobb" =~ /(b.*o.*b)(?{push @all, $1})(*FAIL)/g; printf "got %d matches: %s\n", scalar(@all), "@all"; 

唯一與此相關的問題是,如果測試用例的結果匹配數量在數百萬或更多的數量級上,它會佔用過多的資源。但我知道這是因爲所有的比賽都是先進行分組,然後才計算在內。我正在尋找資源高效的解決方案,只返回計數

+0

如果你在計算機科學意義上的正則表達式,這樣可以使用O(RN)中的NFA很容易完成,其中R和N是正則表達式和輸入字符串的長度)。 – Nabb 2012-02-18 19:02:27

+0

@Nabb但是除非你使用RE2(你實際上可以在Perl中使用),否則你不會得到NFA。你有一個遞歸回溯器。見Russ Cox論文。 – tchrist 2012-02-19 01:32:00

回答

6

看起來好像tchrist已經完成了所有的辛勤工作。如果存儲的比賽,之後他們的計數是吃了太多的資源,那麼你可以只改變正則表達式嵌入代碼僅計算比賽:

my $count = 0; 

"bbboobb" =~ /(b.*o.*b)(?{$count++})(*FAIL)/g; 

print "got $count matches\n"; 
+0

也許一個非捕獲組可以幫助加快速度。可以是'(?:b。* o。* b)'或支持的'/ n'標誌。 – Eily 2018-01-12 16:35:40