超链接正则表达式包括http(s)://无法在C#中工作

时间:2010-03-12 15:42:09

标签: c# regex

我认为这与类似的问题有很大的不同,需要保证一个新问题。

我有以下正则表达式来匹配HTML中的开始超链接标记,包括http(s)://部分以避免mailto:links

<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:rory@domain.com">

然而,当我在我的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:rory@domain.com"">bbc</a>".GetUrls(StringExtensions.HtmlUrlRegexPattern).Count().ShouldEqual(0);

问题似乎出现在我添加的\\b(https?)://部分,删除它会通过正常的URL测试,但无法通过mailto:test。

是谁放弃了任何光明?

3 个答案:

答案 0 :(得分:1)

你是在写这样的正则表达式吗?

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

如果是这样,词边界中的反斜杠太多了。因为它是一个逐字的字符串文字,所以正则表达式编译器看到两个反斜杠就像你写的一样,所以它认为你正在寻找文字序列\b

但无论如何你不需要在那里使用单词边界。您已经指定协议必须紧接在单引号或双引号之前,因此不能以单词字符开头。

答案 1 :(得分:1)

问题是你的正则表达式实际上是在匹配像<a href="\bhttps://...这样的东西。如果删除\\b(这是不必要的),它应该可以工作。请改用:

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

答案 2 :(得分:0)

作为一般建议,在处理正则表达式时,您需要将它们分解为组成部分并使每个部分正常工作。然后,您可以专注于将它们组合在一起以匹配您的输入。有时这很难做到 - 特别是涉及引用或前瞻的复杂表达式,但是你的情况很简单,你应该能够将表达式分解为单独工作的部分。

我认为这应该有效:

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

您不需要在正则表达式中转义/符号,但将它们包装在[ ]组选择器中也没有什么坏处。