从 html 代码中解析链接的正则表达式
Posted
技术标签:
【中文标题】从 html 代码中解析链接的正则表达式【英文标题】:regular expression to parse links from html code 【发布时间】:2010-12-24 22:03:44 【问题描述】:我正在研究一种接受字符串(html 代码)并返回包含 in 中包含的所有链接的数组的方法。
我已经看到了一些选项,例如 html 能力包,但它似乎比这个项目要求的要复杂一些
我也对使用正则表达式感兴趣,因为我没有太多的经验,我认为这将是一个很好的学习机会。
到目前为止我的代码是
WebClient client = new WebClient();
string htmlCode = client.DownloadString(p);
Regex exp = new Regex(@"http://(www\.)?([^\.]+)\.com", RegexOptions.IgnoreCase);
string[] test = exp.Split(htmlCode);
但我没有得到我想要的结果,因为我仍在处理正则表达式
我正在寻找的 sudo 代码是“
【问题讨论】:
虽然不是答案,但这可能是您学习正则表达式时想要使用的工具:rubular.com 由于我们提供有用的自学正则表达式工具,我想说我是The Regex Coach 的忠实粉丝。它看起来比 Rubular 功能更丰富(单步执行和树功能特别有用),但显然需要下载和安装,而不是基于浏览器。 必填链接:***.com/questions/1732348/… 【参考方案1】:如果您正在寻找一个万无一失的解决方案,正则表达式不是您的答案。由于 HTML 语言的复杂性,它们从根本上受到限制,不能用于可靠地从 HTML 文件中解析出链接或其他标签。
长篇版:http://blogs.msdn.com/jaredpar/archive/2008/10/15/regular-expression-limitations.aspx相反,您需要使用实际的 HTML DOM API 来解析链接。
【讨论】:
+1。具体来说,正则表达式和识别正则语言。 HTML 是一种上下文无关语言,因此您需要比正则表达式语言更强大的解析器才能使其 100% 正确。 (en.wikipedia.org/wiki/Chomsky_hierarchy) 可能会得到一个基本正确的解决方案,特别是如果您的正则表达式引擎有一些超出严格正则语法的扩展。但是了解正则表达式的局限性非常重要。我见过很多由于不了解这一点而导致的安全问题。【参考方案2】:正则表达式不是 HTML 的最佳选择。
查看之前的问题:
When is it wise to use regular expressions with HTML? Regexp that matches all the text content of a HTML input相反,你想要一些已经知道如何解析 DOM 的东西;否则,你就是在重新发明***。
【讨论】:
【参考方案3】:其他用户可能会告诉您“不,停止!正则表达式不应该与 HTML 混合!这就像混合漂白剂和氨水!”。这个建议有很多智慧,但这不是全部。
事实上,正则表达式在收集常用格式的链接时工作得很好。但是,更好的方法是使用专门的工具来处理这类事情,例如 HtmlAgilityPack。
如果您使用正则表达式,您可能会匹配 99.9% 的链接,但您可能会错过罕见的意外极端情况或格式错误的 html 数据。
这是我整理的一个函数,它使用 HtmlAgilityPack 来满足您的要求:
private static IEnumerable<string> DocumentLinks(string sourceHtml)
HtmlDocument sourceDocument = new HtmlDocument();
sourceDocument.LoadHtml(sourceHtml);
return (IEnumerable<string>)sourceDocument.DocumentNode
.SelectNodes("//a[@href!='#']")
.Select(n => n.GetAttributeValue("href",""));
此函数创建一个新的 HtmlAgilityPack.HtmlDocument,将包含 HTML 的字符串加载到其中,然后使用 xpath 查询“//a[@href!='#']”来选择页面上的所有链接不要指向“#”。然后我使用 LINQ 扩展 Select 将 HtmlNodeCollection 转换为包含 href 属性值的字符串列表 - 链接指向的位置。
这是一个使用示例:
List<string> links =
DocumentLinks((new WebClient())
.DownloadString("http://google.com")).ToList();
Debugger.Break();
这应该比正则表达式有效得多。
【讨论】:
【参考方案4】:您可以查找类似于 http/https 架构的 url 的任何内容。这不是 HTML 证明,但它会给你一些看起来像 http URL 的东西,我怀疑这是你需要的。您可以添加更多 sachems 和域。 正则表达式查找类似于 URL“in”href 属性的内容(不严格)。
class Program
static void Main(string[] args)
const string pattern = @"href=[""'](?<url>(http|https)://[^/]*?\.(com|org|net|gov))(/.*)?[""']";
var regex = new Regex(pattern);
var urls = new string[]
"href='http://company.com'",
"href=\"https://company.com\"",
"href='http://company.org'",
"href='http://company.org/'",
"href='http://company.org/path'",
;
foreach (var url in urls)
Match match = regex.Match(url);
if (match.Success)
Console.WriteLine("0 -> 1", url, match.Groups["url"].Value);
输出:
href='http://company.com' -> http://company.com href="https://company.com" -> https://company.com href='http://company.org' -> http://company.org href='http://company.org/' -> http://company.org href='http://company.org/path' -> http://company.org
【讨论】:
以上是关于从 html 代码中解析链接的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章