代码之家  ›  专栏  ›  技术社区  ›  o.k.w

从HTML正文提取文本片段(在.NET中)

  •  1
  • o.k.w  · 技术社区  · 15 年前

    我有一个HTML内容,它是由用户通过richtext编辑器输入的,所以它几乎可以是任何内容(少一些不应该在body标签之外的内容,不用担心“head”或doctype等)。 此内容的示例:

    <h1>Header 1</h1>
    <p>Some text here</p><p>Some more text here</p>
    <div align=right><a href="x">A link here</a></div><hr />
    <h1>Header 2</h1>
    <p>Some text here</p><p>Some more text here</p>
    <div align=right><a href="x">A link here</a></div><hr />
    

    技巧是,我只需要提取文本的前100个字符(去掉HTML标记)。我还需要保留换行符,不要打断任何单词。

    因此,上面的输出将类似于:

    Header 1
    Some text here
    
    Some more text here
    
    A link here
    
    Header 2
    Some text here
    
    Some
    

    它有98个字符,并保留换行符。到目前为止,我可以实现的是使用regex去除所有HTML标记:

    Regex.Replace(htmlStr, "<[^>]*>", "")
    

    然后使用regex修剪长度,并使用:

    Regex.Match(textStr, @"^.{1,100}\b").Value
    

    我的问题是,如何保持线路中断?.I得到如下输出:

    Header 1
    Some text hereSome more text here
    A link here
    Header 2
    Some text hereSome more text
    

    注意到连词了吗?也许有人能告诉我解决这个问题的其他方法。谢谢!

    附加信息 :我的目的是从一组HTML内容生成纯文本摘要。我想这有助于澄清这个问题。

    4 回复  |  直到 15 年前
        1
  •  2
  •   phairoh    15 年前

    我想我解决这个问题的方法是把它看成一个简单的浏览器。创建一个基标记类,使用innerhtml属性和一个虚拟方法printElement将其抽象化。

    接下来,为您关心的每个HTML标记创建类,并从您的基类继承。从您的示例来看,您最关心的标签是h1、p、a和hr。实现printElement方法,使其返回一个字符串,该字符串根据innerhtml正确打印出元素(例如p类的printElement将返回“\n[innerhtml]\n”)。

    接下来,构建一个解析器,该解析器将通过HTML进行解析,并确定要创建哪个对象,然后将这些对象添加到队列中(树会更好,但对于您的目的来说似乎不必要)。

    最后,遍历调用每个元素的printElement方法的队列。

    可能比你计划的要多,但这是一个比简单使用regex强大得多的解决方案,如果你决定在将来改变主意并想显示简单的样式,这只是返回并修改printElement方法的问题。

        2
  •  1
  •   Marc Gravell    15 年前

    有关信息,用regex剥离HTML是…充满了微妙的问题。这个 HTML Agility Pack 可能会更强壮,但仍然会遭受“一起流血”的痛苦:

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);
    string text = doc.DocumentNode.InnerText;
    
        3
  •  0
  •   Arun M    15 年前

    一种方法是分三步剥离HTML:

    Regex.Replace(htmlStr, "<[^/>]*>", "") // don't strip </.*>
    Regex.Replace(htmlStr, "</p>", "\r\n") // all paragraph ends are replaced w/ new line
    Regex.Replace(htmlStr, "<[^>]*>", "") // replace remaining </.*>
    
        4
  •  0
  •   o.k.w    15 年前

    好吧,我需要关闭这个,尽管没有理想的解决方案。由于我的应用程序中使用的HTML标记非常常见(没有表格、列表等),很少或没有嵌套,所以我所做的就是在用户输入后保存HTML片段之前先对其进行预处理。

    • 删除所有换行符
    • 向所有块标记添加换行前缀(例如,DIV、P、HR、H1/2/3/4等)

    在将它们提取出来显示为纯文本之前,请使用regex删除HTML标记并保留换行符。几乎没有什么火箭科学,但对我有用。