2010-01-14 48 views
3

我目前使用下面的正則表達式來驗證網址:需要一個正則表達式來驗證URL並支持20%和()

^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\[email protected])? (?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|edu|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$ 

我借這個從什麼地方在網絡上(不記得其中),以改善在此:

^((https?|file|ftp|gopher|news|nntp):\/\/)([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$ 

但是,這些都不是能夠驗證這個URL(其應該是有效的):

http://somedomain.com/users/1234/images/Staff%20Photos%202008/FirstName%20LastName_1%20(Small).jpg 

問題是%20和圓括號()。儘可能地嘗試,我無法得到上面的任何一個正則表達式來正確驗證上面的url而不會破壞別的東西。我沒有經驗寫正則表達式,所以也沒有幫助。所有其他網絡搜索結果我發現這樣的愚蠢的東西失敗:

http://www.test..com 

幫助將不勝感激。

+1

我不認爲正則表達式是正確的工具。爲什麼你必須使用正則表達式有什麼原因嗎? – 2010-01-14 23:53:17

+0

你在用什麼語言?也許有另一種方法來驗證它。 – 2010-01-15 02:53:38

+0

嗨,我實際上使用C#在ASP.NET MVC中編寫Web應用程序。我的驗證層使用Regex來確保輸入的URL有效(很像電子郵件和電話驗證)。這些URL指示Internet和Intranet上的文件位置。當表單發佈時,您是否看到比正則表達式更好的方法來執行此驗證? – 2010-01-15 15:50:22

回答

4

你確認兩件事情具有相同的正則表達式:

  • 形成嘛 - 是不是語法正確的?
  • 合理 - 協議和頂級域名似乎合理嗎?

分離這些驗證可能是有益的。您可以使用此正則表達式來檢查URI是否格式正確。這是從RFC 3986, Uniform Resource Identifiers (URI): Generic Syntax,附錄B(第50頁):

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? 

如果URI此正則表達式匹配,它的良好形成。比賽團體給你的各個部分,分別是:

scheme = $2 
authority = $4 
path  = $5 
query  = $7 
fragment = $9 

讓我們來看看你給什麼出來的樣品的URI:

2 (scheme) : "http" 
4 (authority): "somedomain.com" 
5 (path)  : "https://stackoverflow.com/users/1234/images/Staff%20Photos%202008/FirstName%20LastName_1%20(Small).jpg" 
7 (query) : nil 
9 (fragment) : nil 

現在,你已經得到了各個部分,你可以檢查每一個是否合理。例如,從權威得到頂級域名,這正則表達式適用於機關:

\.([^.])$ 

1組爲您提供頂級域名(COM,組織等),然後你就可以覈對列表。

+0

我從來沒有聽說過不使用單個正則表達式來測試窗體和合理性。這個想法很好,但需要更多的工作。你有推薦的(路徑)正則表達式嗎? – 2010-01-21 22:45:39

+1

我不認爲你需要額外的路徑正則表達式。對於權威機構,使用我剛纔給出的正則表達式來提取它並根據你的列表(com,org等)進行檢查。根據你的清單(http,ftp等)檢查方案。我不會檢查太多 - 只要知道它的結構良好已經使您獲得了大部分好處;如果現在或將來引入新的頂級域名(TLD)和協議時,更多的檢查將導致遞減的收益減少,從而導致您拒絕正確的URI。 – 2010-01-21 23:51:42