2012-10-18 46 views
0

我目前正在建設使用Asp.net它使用正則表達式如下的系統,C#,MVC2:爲什麼這個電子郵件正則表達式在Mvc上如此慢?

^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$ 

這是一個電子郵件的正則表達式驗證一個「有效」的電子郵件地址格式。我的代碼如下:

if (!Regex.IsMatch(model.Email, @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$")) 
       ModelState.AddModelError("Email", "The field Email is invalid."); 

正則表達式工作正常,但是如果一個特別長的字符串傳遞給正則表達式驗證電子郵件,它是無效的會導致系統保持對「工作」而沒有解決這一頁。例如,這是我試圖通過的數據:

iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii 

上面的字符串導致系統基本上鎖定。我想知道爲什麼,如果我可以使用一個正則表達式完成相同的事情,也許更簡單一些。我的目標是,像一個不正確形成的e-mail地址例如,下面的不通過:

[email protected] 
+0

@Liam,這是公牛。有可能編寫低效的正則表達式,但是你的寬筆觸一般主義在這裏沒有幫助。 – spender

+6

請閱讀此:http://www.codinghorror.com/blog/2006/01/regex-performance.html我建議嘗試構建一個'System.Net.Mail.MailAddress'並捕獲錯誤檢測到錯誤的地址。 – spender

回答

6

你嵌套了重複運營商共享相同的字符,這容易導致災難性的回溯。

例如:([-.\w]*[0-9a-zA-Z])*

這表示:匹配0以上的-._0-9a-zA-Z後跟單個0-9a-zA-Z,一次或多次。

i屬於這兩類。

因此,當在iiiiiiii...上運行時,正則表達式匹配(several "i"s followed by one "i") several times(這是很多排列組合)的每種可能的排列方式。

In general, validating email addresses with a regular expression is hard.

+0

有沒有辦法修改正在使用的正則表達式來完成相同的功能並刪除嵌套的運算符? –

+1

+1爲災難性的回溯 – spender

+0

我建議從第一個類中移除'\ w'並將'*'應用於第二個類而不是第一個類 - 看看它是否仍然符合您的「好」情況。 (但總的來說,我建議不要試圖這樣做。) – Rawling

相關問題