2010-03-12 44 views
0

我認爲這與類似的問題有很大的不同,以保證一個新的。超鏈接正則表達式包括http(s)://不在C#中工作

我有以下的正則表達式匹配HTML開始超級鏈接標籤,包括HTTP(S):爲了避免郵寄地址//部分:連接

<a[^>]*?href=[""'](?<href>\\b(https?)://[^\[\]""]+?)[""'][^>]*?> 

當我運行此通過Nregex(帶逃脫刪除)它正確地匹配以下測試用例:

<a href="http://www.bbc.co.uk"> 

<a href="http://bbc.co.uk"> 

<a href="https://www.bbc.co.uk"> 

<a href="mailto:[email protected]"> 

但是,當我在我的C#代碼中運行它失敗。下面是匹配代碼:

public static IEnumerable<string> GetUrls(this string input, string matchPattern) 
    { 
     var matches = Regex.Matches(input, matchPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); 
     foreach (Match match in matches) 
     { 
      yield return match.Groups["href"].Value; 
     } 
    } 

而且我的測試:

@"<a href=""https://www.bbc.co.uk"">bbc</a>".GetUrls(StringExtensions.HtmlUrlRegexPattern).Count().ShouldEqual(1); 

@"<a href=""mailto:[email protected]"">bbc</a>".GetUrls(StringExtensions.HtmlUrlRegexPattern).Count().ShouldEqual(0); 

的問題似乎是我在其中添加了\\b(https?)://部分,刪除此通過正常的URL測試,但失敗的mailto:測試。

任何人流光了?

+0

我們沒有做過正則表達式不能解析HTML的東西了嗎?你必須使用一個HTML解析器,其他的都不能保證你的結果。正則表達式解析href屬性的值是另一個問題,雖然... – annakata 2010-03-12 15:58:31

+0

您究竟如何定義'matchPattern'? – 2010-03-12 16:11:57

+0

@Tim'public static string HtmlUrlRegexPattern = @「] *?href = [」''](? \\ b(https?):// [^ \ [\]「」] +?)[「」 '] [^>] *?>「;' – roryf 2010-03-12 16:35:38

回答

1

你在寫這樣的正則表達式嗎?

@"<a[^>]*?href=[""'](?<href>\\b(https?)://[^\[\]""]+?)[""'][^>]*?>" 

如果是這樣,那麼在單詞邊界中有太多反斜槓。因爲它是一個逐字字符串文字,所以正則表達式編譯器會像您寫它一樣看到兩個反斜槓,所以它認爲您正在查找文字序列\b

但是,無論如何您都不需要使用字邊界。您已經指定協議必須立即以單引號或雙引號開頭,因此它不能以單詞字符開頭。

0

作爲一般建議,在處理正則表達式時,需要將它們分解爲組成部分並使每個部分正確工作。然後,您可以專注於將它們組裝在一起以匹配您的輸入。有時候這很難做到 - 特別是涉及引用或前瞻的複雜表達式,但是您的案例非常簡單,您應該能夠將表達式分解爲單獨運行的部分。

我認爲這應該工作:

@"(https?):[/][/][^\[\]""]+?)[""'][^>]*?" 

你不需要逃脫正則表達式/符號,但它不會傷害到他們包裹在[ ]組選擇。

+0

您的最後一句話不正確:'https?'會匹配'http'或'https'。你指的是'(https)?'。 – 2010-03-12 16:13:27

+0

你是對的 - 我的錯。 – LBushkin 2010-03-12 16:19:54

1

問題是,你的正則表達式實際上看起來像<a href="\bhttps://...。如果你刪除\\b(這是不必要的)它應該工作。用這個代替:

<a[^>]*?href=[""'](?<href>(https?)://[^\[\]""]+?)[""'][^>]*?>