65.9K
CodeProject 正在变化。 阅读更多。
Home

HTML 标签剥离器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.52/5 (9投票s)

2007年7月18日

CPOL

2分钟阅读

viewsIcon

117843

downloadIcon

2532

一种快速从 HTML 片段中剥离 HTML 标签,只留下可见文本的方法

引言

本文介绍了一种简单的去除HTML标签的方法,类似于PHP的strip_tags()函数。这通常在CMS系统中很有用,您需要在其中存储仅文本版本的文章,例如,以便允许对所有文章进行全文搜索。

背景

在这种情况下,去除标签意味着仅保留HTML文档或HTML片段的可见文本。这意味着排除所有HTML注释以及所有HTML <script><style><noscript> 块。

我还必须提到,从这种去除操作中得到的结果文本可以通过替换命名HTML实体(例如 &quot;&&copy;&nbsp; 等)和未命名的HTML实体(例如 &#355;)来进一步处理,并将其替换为相应的字符。只需将方法的相应参数(即 replaceNamedEntitiesreplaceNumberedEntities)设置为 true。但是,请记住,这可能会显著降低执行时间。

Using the Code

此操作仅涉及一种方法。我将其命名为 HtmlStripTags,没有受到任何启发。

  • htmlContent:要处理的HTML内容
  • replaceNamedEntities:是否替换HTML命名实体,例如 &nbsp;
  • replaceNumberedEntities:是否替换HTML编号实体,即Unicode HTML表示形式,例如 &#355;
public static string HtmlStripTags(string htmlContent, 
    bool replaceNamedEntities, bool replaceNumberedEntities)
{
    if (htmlContent == null)
        return null;
    htmlContent = htmlContent.Trim();
    if (htmlContent == string.Empty)
        return string.Empty;

    int bodyStartTagIdx = htmlContent.IndexOf("<body", 
        StringComparison.CurrentCultureIgnoreCase);
    int bodyEndTagIdx = htmlContent.IndexOf("</body>", 
        StringComparison.CurrentCultureIgnoreCase);

    int startIdx = 0, endIdx = htmlContent.Length - 1;
    if (bodyStartTagIdx >= 0)
        startIdx = bodyStartTagIdx;
    if (bodyEndTagIdx >= 0)
        endIdx = bodyEndTagIdx;

    bool insideTag = false,
        insideAttributeValue = false,
        insideHtmlComment = false,
        insideScriptBlock = false,
        insideNoScriptBlock = false,
        insideStyleBlock = false;
    char attributeValueDelimiter = '"';

    StringBuilder sb = new StringBuilder(htmlContent.Length);
    for (int i = startIdx; i <= endIdx; i++)
    {

        // html comment block
        if (!insideHtmlComment)
        {
            if (i + 3 < htmlContent.Length &&
                htmlContent[i] == '<' &&
                ...
                ...
                ...

关注点

为了实现最大性能,我避免使用正则表达式。RegExs 尚未成为 .NET Framework 最强大的部分。此外,我认为此任务足够简单,不需要使用这种通用的工具。我运行了基准测试,将此实现与CodeProject.com上提供的另一种实现进行比较,将HTML转换为纯文本,该实现主要使用正则表达式。我发现,在解析大型HTML内容(80+ KB)时不替换任何HTML实体时,它仍然可以提供5倍的性能提升,即在Intel Core Duo @ 1,83GHz和1GB RAM上约为5微秒。当然,它不如使用正则表达式优雅。我只是最大化了性能。

历史

  • 2007年7月18日 -- 发布原始版本
  • 2007年11月8日 -- 更新文章内容和下载
© . All rights reserved.