C# 解析HTML文档:正则表达式还是LINQ?
试图解析HTML文档并提取某些元素(指向文本文件的任何链接) 当前的策略是将HTML文档加载到字符串中。然后查找指向文本文件的链接的所有实例。它可以是任何文件类型,但对于这个问题,它是一个文本文件 最终目标是拥有字符串对象的C# 解析HTML文档:正则表达式还是LINQ?,c#,regex,linq,parsing,linq-to-xml,C#,Regex,Linq,Parsing,Linq To Xml,试图解析HTML文档并提取某些元素(指向文本文件的任何链接) 当前的策略是将HTML文档加载到字符串中。然后查找指向文本文件的链接的所有实例。它可以是任何文件类型,但对于这个问题,它是一个文本文件 最终目标是拥有字符串对象的IEnumerable列表。这一部分很容易,但解析数据是个问题 <html> <head><title>Blah</title> </head> <body> <br/> <div>
IEnumerable
列表。这一部分很容易,但解析数据是个问题
<html>
<head><title>Blah</title>
</head>
<body>
<br/>
<div>Here is your first text file: <a href="http://myServer.com/blah.txt"></div>
<span>Here is your second text file: <a href="http://myServer.com/blarg2.txt"></span>
<div>Here is your third text file: <a href="http://myServer.com/bat.txt"></div>
<div>Here is your fourth text file: <a href="http://myServer.com/somefile.txt"></div>
<div>Thanks for visiting!</div>
</body>
</html>
都不是。将其加载到(X/HT)MLDocument中并使用XPath,这是处理XML的标准方法,功能非常强大。要查看的函数是和
因为您显然在使用HTML(而不是XHTML),所以应该使用。大多数方法和属性都与相关的XML类匹配
使用XPath的示例实现:
HtmlDocument doc = new HtmlDocument();
doc.Load(new StringReader(@"<html>
<head><title>Blah</title>
</head>
<body>
<br/>
<div>Here is your first text file: <a href=""http://myServer.com/blah.txt""></div>
<span>Here is your second text file: <a href=""http://myServer.com/blarg2.txt""></span>
<div>Here is your third text file: <a href=""http://myServer.com/bat.txt""></div>
<div>Here is your fourth text file: <a href=""http://myServer.com/somefile.txt""></div>
<div>Thanks for visiting!</div>
</body>
</html>"));
HtmlNode root = doc.DocumentNode;
// 3 = ".txt".Length - 1. See http://stackoverflow.com/questions/402211/how-to-use-xpath-function-in-a-xpathexpression-instance-programatically
HtmlNodeCollection links = root.SelectNodes("//a[@href['.txt' = substring(., string-length(.)- 3)]]");
IList<string> fileStrings;
if(links != null)
{
fileStrings = new List<string>(links.Count);
foreach(HtmlNode link in links)
fileStrings.Add(link.GetAttributeValue("href", null));
}
else
fileStrings = new List<string>(0);
HtmlDocument doc=新的HtmlDocument();
文件加载(新StringReader(@)
废话
这是您的第一个文本文件:
这是您的第二个文本文件:
这是您的第三个文本文件:
这是您的第四个文本文件:
谢谢光临!
"));
HtmlNode root=doc.DocumentNode;
//3=“.txt”长度-1。看见http://stackoverflow.com/questions/402211/how-to-use-xpath-function-in-a-xpathexpression-instance-programatically
HtmlNodeCollection links=root.SelectNodes(//a[@href['.txt'=子字符串(,字符串长度(.)-3)]);
IList文件串;
如果(链接!=null)
{
fileStrings=新列表(links.Count);
foreach(链接中的HtmlNode链接)
Add(link.GetAttributeValue(“href”,null));
}
其他的
fileStrings=新列表(0);
我建议使用正则表达式。为什么?
- 灵活(不区分大小写,易于识别) 将新的文件扩展名、元素添加到 支票等)
- 快写
- 快跑
href=“([^”]*\.txt)”
说明:
- 它用括号括起来 文件名,这将导致 您可以访问的“捕获组” 在找到每个匹配项之后
- 它必须通过使用 正则表达式转义字符,一个反斜杠
- 它必须匹配任何字符,除了
双引号:[^“]直到找到
“.txt”
string txtExp = "href=\"([^\\\"]*\\.txt)\"
然后您可以迭代您的匹配项:
Matches txtMatches = Regex.Matches(input, exp, RegexOptions.IgnoreCase);
foreach(Match m in txtMatches) {
string filename = m.Groups[1]; // this is your captured group
}
除了Matthew Flaschen的建议, (例如,如果您患有X?L过敏爆发)
它有时会有不好的表现-我想是因为实现有时很有趣,没有一些(次要的)智能助手,本机COM接口有点笨拙,但我发现它是一种健壮、稳定、直观/可探索的解析和操作HTML的方法。REGEX速度不快,事实上,它比.NET中本机字符串解析的东西慢。别相信我,你自己看看吧 上面的例子没有一个比直接访问DOM更快
HTMLDocument doc = wb.Document;
var links = doc.Links;
你愿意使用开源HTML解析器吗?@JD:当然!正如Matthew所说,HTML敏捷包听起来值得一看。你是想建议这个还是另外一个?@Philoushka我想建议HTML Agility Pack。。。“太棒了!”Matthew:HTML敏捷包在大约5分钟的实现过程中为我提供了所需的东西。它带有样品和来源。西蒙·穆里尔的荣誉!敏捷包中现在也有一些对“LINQ到HTML”的支持。@杰夫:这是一个优秀的代码示例。谢谢你的意见!当OP明确表示“以结尾”时,它将匹配href中的任何位置的.txt。在我看来,正则表达式在这里是不合适的。@Matthew:不,它将只匹配以(.txt)结尾的HREF我不认为HREF在中间包含引号。不要尝试使用正则表达式来解析非正则语言。我理解从DOM/XPath的观点来处理这个问题的愿望。但是我的理由是,ReEX实现对输入数据的假设很小。显然,如果OP可以做出假设,特别是很好的假设。-形成文档时,DOM方法更“干净”。@Svante:我认为正则表达式非常擅长从非规则数据中查找已知模式。想想你用正则表达式搜索了多少次。此外,OP想要一个正则表达式示例。你实际上是建议他通过COM interop从.NET使用IE的HTML解析器?。。。。
HTMLDocument doc = wb.Document;
var links = doc.Links;