正则表达式提取HTML正文内容

时间:2008-12-10 14:53:56

标签: c# html regex xhtml

我正在寻找一个正则表达式语句,它允许我从XHTML文档的body标签之间提取HTML内容。

我需要解析的XHTML将是非常简单的文件,例如,我不必担心JavaScript内容或<![CDATA[标记。

以下是我要解析的HTML文件的预期结构。由于我完全知道我将要使用的HTML文件的所有内容,因此这个HTML代码段几乎涵盖了我的整个用例。如果我能得到一个正则表达式来提取这个例子的主体,我会很高兴。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>
    </title>
  </head>
  <body contenteditable="true">
    <p>
      Example paragraph content
    </p>
    <p>
      &nbsp;
    </p>
    <p>
      <br />
      &nbsp;
    </p>
    <h1>Header 1</h1>
  </body>
</html>

从概念上讲,我一直在尝试构建一个匹配内部正文内容的所有正则表达式字符串。有了这个,我会使用C#Regex.Split()方法来获取正文内容。我以为这个正则表达式:

((.|\n)*<body (.)*>)|((</body>(*|\n)*)

...可以解决这个问题,但它似乎与我在RegexBuddy中的测试内容完全无关。

6 个答案:

答案 0 :(得分:23)

这会有用吗?

((?:.(?!<body[^>]*>))+.<body[^>]*>)|(</body\>.+)

当然,您需要添加必要的\s才能考虑< body ...>(带空格的元素),如:

((?:.(?!<\s*body[^>]*>))+.<\s*body[^>]*>)|(<\s*/\s*body\s*\>.+)

第二个想法,我不确定为什么我需要一个负面的预测...这也应该有效(对于格式良好的xhtml文档):

(.*<\s*body[^>]*>)|(<\s*/\s*body\s*\>.+)

答案 1 :(得分:9)

使用XML解析器比使用正则表达式更容易解析XHTML。我知道这不是你问的问题,但是XML解析器能够快速导航到body节点并返回其内容,而不会出现正则表达式给你的任何标记映射问题。

编辑: 回应此处的评论; XML解析器太慢了。

有两种XML解析器,一种叫做DOM,大而重,简单友好,它可以在你做任何事情之前从文档中构建一棵树。另一个叫做SAX,速度快,工作量大,顺序读取文件。您将希望SAX找到Body标签。

DOM方法适用于多种用途,提取标签并查找谁是孩子。 SAX解析器按顺序读取文件,然后快速获取您所需的信息。正则表达式不会比SAX解析器快,因为它们都只是遍历文件和模式匹配,除了正则表达式不会在找到正文标记后退出,因为正则表达式没有内置XML知识。实际上,您的SAX解析器可能使用小块正则表达式来查找每个标记。

答案 2 :(得分:5)

String toMatch="aaaaaaaaaaabcxx sldjfkvnlkfd <body>i m avinash</body>";
Pattern pattern=Pattern.compile(".*?<body.*?>(.*?)</body>.*?");
Matcher matcher=pattern.matcher(toMatch);
if(matcher.matches()) {
    System.out.println(matcher.group(1));
}

答案 3 :(得分:3)

/<body[^>]*>(.*)</body>/s

替换为

\1

答案 4 :(得分:3)

为什么你不能通过

分开它
</{0,1}body[^>]*> 

并取第二个字符串?我相信它会比寻找一个巨大的正则表达式快得多。

答案 5 :(得分:1)

匹配第一个正文标记:<\s*body.*?>

匹配上一个正文标记:<\s*/\s*body.*?>

(注意:我们考虑了标签中间的空格,这是完全有效的标记btw)

将它们组合在一起就可以得到所有内容,包括正文标记:<\s*body.*?>.*?<\s*/\s*body.*?>。并确保您使用的Singleline模式会忽略换行符。

这适用于VB.NET,希望其他人也一样!