如何使用.NET中的Regex在2个标记之间提取字符串?

时间:2011-09-21 21:01:22

标签: c# .net regex string-parsing

我有一个网页来源,我需要提取正文。所以</head><body></body></html>之间的任何内容。

我尝试过以下方法但没有成功:

var match = Regex.Match(output, @"(?<=\</head\>\<body\>)(.*?)(?=\</body\>\</html\>)");

它找到一个字符串,但在</body></html>之前很久才将其删除。我根据RegEx cheat sheet转义了字符。

我缺少什么?

4 个答案:

答案 0 :(得分:6)

我建议使用HtmlAgilityPack - 用正则表达式解析HTML非常非常脆弱。

最新版本甚至支持Linq,因此您可以获得这样的内容:

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://stackoverflow.com");
string html = doc.DocumentNode.Descendants("body").Single().InnerHtml;

答案 1 :(得分:2)

正如许多人在这里所说的那样,正则表达式并不适用于这种html处理。如果没有您的示例网页/ html,我只能说尝试删除?中的非贪婪(.*?)量词并尝试。毕竟,一个html页面只有一个头部和身体。

答案 2 :(得分:1)

虽然正则表达式肯定不是完成此任务的最佳工具,但我想提出一些建议和要点:

  1. 取消使用尖括号 - 使用字符串前面的@,它们将进入正则表达式,并且不需要为.NET正则表达式进行转义
  2. 使用正则表达式,您需要确保头部/身体标记组合之间没有任何空格。
  3. 使用正则表达式,body标签不能具有任何属性。
  4. 我会建议更像:

    (?<=</head>\s*<body(\s[^>]*)?>)(.*?)(?=</body>\s*</html>)
    

    这似乎对我来说对这个页面的来源有用了!

答案 3 :(得分:0)

正如其他人所说,处理这个问题的正确方法是使用特定于HTML的工具。我只是想指出那个备忘单的一些问题。

首先,尖括号是错误的:你不需要逃避它们。事实上,它错了两次:它还说\<\>匹配字边界,这对于.NET来说都是不正确的,并且与关于转义尖括号的建议不兼容。

该作弊表只是一个正则表达式语法元素的随机集合;他们中的大多数都可以在大多数口味中使用,但是很多都保证以你的特定口味工作,无论它是什么。我建议您忽略它,而是依赖于特定于.NET的文档或Regular-Expressions.info。书籍Mastering Regular ExpressionsRegular Expressions Cookbook也非常出色。

至于你的正则表达式,我看不出它的行为方式就像你说的那样。如果它会失败,我希望它完全失败。您的HTML文档中是否包含CDATA部分或带有</body></html>的SGML评论?或者它真的是两个或多个HTML文档一起运行吗?