Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解析HTML文档:正则表达式还是LINQ?_C#_Regex_Linq_Parsing_Linq To Xml - Fatal编程技术网

C# 解析HTML文档:正则表达式还是LINQ?

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>

试图解析HTML文档并提取某些元素(指向文本文件的任何链接)

当前的策略是将HTML文档加载到字符串中。然后查找指向文本文件的链接的所有实例。它可以是任何文件类型,但对于这个问题,它是一个文本文件

最终目标是拥有字符串对象的
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;