2012-10-10 20 views
0

當運行下面的代碼CPU負載去的方式了,它需要一個很長時間在更大的文件:正則表達式極其緩慢大型文檔

string pattern = @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"; 
Regex regex = new Regex(
     pattern, 
     RegexOptions.None | RegexOptions.Multiline | RegexOptions.IgnoreCase); 

MatchCollection matches = regex.Matches(input); // Here is where it takes time 
MessageBox.Show(matches.Count.ToString()); 

foreach (Match match in matches) 
{ 
    ... 
} 

任何想法如何加快步伐?

+0

你能量化「長時間」嗎? –

+0

在大型文件上,每個文件最多可能需要1分鐘 – Jacqueline

+0

多大? –

回答

2

更改RegexOptions.None | RegexOptions.Multiline | RegexOptions.IgnoreCaseRegexOptions.Compiled產生相同的結果(因爲你的模式不包含任何文字字母或^/$)。

在我的機器上,這樣可以縮短從46秒到21秒(這對我來說似乎很慢,但對您來說可能足夠好)鏈接的樣本文檔所用的時間。

編輯:所以我研究了一些,發現了真正的問題。

問題在於你的正則表達式的前半部分:\w+([-.]\w+)*\.\w+([-.]\w+)*@。當匹配實際包含@符號的輸入部分時,此功能正常工作,但對於只匹配\w+([-.]\w+)*\.\w+([-.]\w+)*而不是後跟@的部分,正則表達式引擎會浪費大量時間回溯並重試序列中的每個位置(並再次失敗,因爲還沒有@

您可以通過強制匹配修復此使用\b單詞邊界處開始:

string pattern = @"\b\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"; 

在示例文檔,這將產生相同的10個結果在1秒內。

+1

你也許當你在它以及擺脫'None'選項。 –

0

要回答如何改變它,你需要告訴我們,它應該匹配什麼。

問題可能出現在最後部分@\w+([-.]\w+)*\.\w+([-.]\w+)*。在一個字符串「[email protected]」它將不得不嘗試許多可能性,直到它找到一個匹配。可能有點Catastrophic Backtracking

所以,你需要以更好,更「獨特」的方式定義你的模式。你真的需要「Dash/dot - dot - dash/dot」嗎?