正则表达式从HTML中提取文本

时间:2008-10-08 01:43:39

标签: html regex html-content-extraction text-extraction

我想从一般HTML页面中提取所有文本(显示与否)。

我想删除

  • 任何HTML标记
  • 任何javascript
  • 任何CSS样式

是否有正则表达式(一个或多个)可以实现?

12 个答案:

答案 0 :(得分:15)

删除javascript和CSS:

<(script|style).*?</\1>

删除标签

<.*?>

答案 1 :(得分:11)

您无法使用正则表达式真正解析HTML。这太复杂了。 RE根本不会正确处理<![CDATA[个部分。此外,某些常见的HTML内容(如&lt;text>)可以在浏览器中作为正确的文本使用,但可能会让一个天真的RE感到困惑。

使用正确的HTML解析器,您会更快乐,更成功。 Python人经常使用Beautiful Soup来解析HTML并删除标签和脚本。


此外,浏览器在设计上容忍格式错误的HTML。因此,您经常会发现自己试图解析明显不合适的HTML,但在浏览器中运行正常。

您可以使用RE解析错误的HTML。它需要的只是耐心和努力。但是使用别人的解析器通常更简单。

答案 2 :(得分:6)

需要一个正则表达式解决方案(在php 中),它将返回纯文本(或者比PHPSimpleDOM更好),但速度要快得多。以下是我提出的解决方案:

function plaintext($html)
{
    // remove comments and any content found in the the comment area (strip_tags only removes the actual tags).
    $plaintext = preg_replace('#<!--.*?-->#s', '', $html);

    // put a space between list items (strip_tags just removes the tags).
    $plaintext = preg_replace('#</li>#', ' </li>', $plaintext);

    // remove all script and style tags
    $plaintext = preg_replace('#<(script|style)\b[^>]*>(.*?)</(script|style)>#is', "", $plaintext);

    // remove br tags (missed by strip_tags)
    $plaintext = preg_replace("#<br[^>]*?>#", " ", $plaintext);

    // remove all remaining html
    $plaintext = strip_tags($plaintext);

    return $plaintext;
}

当我在一些复杂的网站上测试它时(论坛似乎包含了一些更难解析的html),这个方法返回了与PHPSimpleDOM明文相同的结果,只是更快,更快。它还正确处理了列表项(li标签),而PHPSimpleDOM没有。

至于速度:

  • SimpleDom:0.03248秒。
  • RegEx:0.00087 sec。

快37倍!

答案 3 :(得分:4)

考虑使用正则表达式这样做是令人生畏的。你考虑过XSLT吗? XPath表达式,用于提取XHTML文档中的所有文本节点,减去脚本&amp;风格内容,将是:

//body//text()[not(ancestor::script)][not(ancestor::style)]

答案 4 :(得分:2)

简单HTML的最简单方法(Python中的示例):

text = "<p>This is my> <strong>example</strong>HTML,<br /> containing tags</p>"
import re
" ".join([t.strip() for t in re.findall(r"<[^>]+>|[^<]+",text) if not '<' in t])

返回:

'This is my> example HTML, containing tags'

答案 5 :(得分:2)

这是删除最复杂的html标签的功能。

function strip_html_tags( $text ) 
{

$text = preg_replace(
    array(
        // Remove invisible content
        '@<head[^>]*?>.*?</head>@siu',
        '@<style[^>]*?>.*?</style>@siu',
        '@<script[^>]*?.*?</script>@siu',
        '@<object[^>]*?.*?</object>@siu',
        '@<embed[^>]*?.*?</embed>@siu',
        '@<applet[^>]*?.*?</applet>@siu',
        '@<noframes[^>]*?.*?</noframes>@siu',
        '@<noscript[^>]*?.*?</noscript>@siu',
        '@<noembed[^>]*?.*?</noembed>@siu',

        // Add line breaks before & after blocks
        '@<((br)|(hr))@iu',
        '@</?((address)|(blockquote)|(center)|(del))@iu',
        '@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
        '@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
        '@</?((table)|(th)|(td)|(caption))@iu',
        '@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
        '@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
        '@</?((frameset)|(frame)|(iframe))@iu',
    ),
    array(
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
        "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
        "\n\$0", "\n\$0",
    ),
    $text );

// Remove all remaining tags and comments and return.
return strip_tags( $text );
    }

答案 6 :(得分:1)

使用perl语法定义正则表达式,一个开头可能是:

!<body.*?>(.*)</body>!smi

然后将以下替换应用于该组的结果:

!<script.*?</script>!!smi
!<[^>]+/[ \t]*>!!smi
!</?([a-z]+).*?>!!smi
/<!--.*?-->//smi

这当然不会很好地将事物格式化为文本文件,但它会删除所有HTML(大多数情况下,有些情况下它可能无法正常工作)。但更好的想法是使用您正在使用的任何语言的XML解析器来正确解析HTML并从中提取文本。

答案 7 :(得分:1)

如果您正在使用PHP,请尝试在SourceForge上提供的简单HTML DOM。

否则,谷歌html2text,你会发现不同语言的各种实现基本上使用一系列正则表达式来吸取所有标记。这里要小心,因为有时可以保留没有结尾的标签,以及诸如&amp ;;之类的特殊字符。 (这是&amp; amp;)。

另外,请注意评论和Javascript,因为我发现处理正则表达式特别烦人,为什么我通常只是想让一个免费的解析器为我做所有的工作。

答案 8 :(得分:1)

不确定this page可以提供帮助。

答案 9 :(得分:1)

你不能只使用C#提供的WebBrowser控件吗?

        System.Windows.Forms.WebBrowser wc = new System.Windows.Forms.WebBrowser();
        wc.DocumentText = "<html><body>blah blah<b>foo</b></body></html>";
        System.Windows.Forms.HtmlDocument h = wc.Document;
        Console.WriteLine(h.Body.InnerText);

答案 10 :(得分:1)

string decode = System.Web.HttpUtility.HtmlDecode(your_htmlfile.html);
                Regex objRegExp = new Regex("<(.|\n)+?>");
                string replace = objRegExp.Replace(g, "");
                replace = replace.Replace(k, string.Empty);
                replace.Trim("\t\r\n ".ToCharArray());

then take a label and do "label.text=replace;" see on label out put

答案 11 :(得分:0)

我相信你可以做到

document.body.innerText

将返回文档中所有文本节点的内容,可见或不可见。

[edit(olliej):叹息没关系,这只适用于Safari和IE,我不能每晚下载一个firefox,看它是否存在于trunk中: - /] < / p>

相关问题