我认为这与类似的问题有很大的不同,需要保证一个新问题。
我有以下正则表达式来匹配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。
答案 0 :(得分:1)
你是在写这样的正则表达式吗?
@"<a[^>]*?href=[""'](?<href>\\b(https?)://[^\[\]""]+?)[""'][^>]*?>"
如果是这样,词边界中的反斜杠太多了。因为它是一个逐字的字符串文字,所以正则表达式编译器看到两个反斜杠就像你写的一样,所以它认为你正在寻找文字序列\b
。
但无论如何你不需要在那里使用单词边界。您已经指定协议必须紧接在单引号或双引号之前,因此不能以单词字符开头。
答案 1 :(得分:1)
问题是你的正则表达式实际上是在匹配像<a href="\bhttps://...
这样的东西。如果删除\\b
(这是不必要的),它应该可以工作。请改用:
<a[^>]*?href=[""'](?<href>(https?)://[^\[\]""]+?)[""'][^>]*?>
答案 2 :(得分:0)
作为一般建议,在处理正则表达式时,您需要将它们分解为组成部分并使每个部分正常工作。然后,您可以专注于将它们组合在一起以匹配您的输入。有时这很难做到 - 特别是涉及引用或前瞻的复杂表达式,但是你的情况很简单,你应该能够将表达式分解为单独工作的部分。
我认为这应该有效:
@"(https?):[/][/][^\[\]""]+?)[""'][^>]*?"
您不需要在正则表达式中转义/
符号,但将它们包装在[ ]
组选择器中也没有什么坏处。