从 HTML 正文中提取文本片段(在 .NET 中)
Posted
技术标签:
【中文标题】从 HTML 正文中提取文本片段(在 .NET 中)【英文标题】:Extracting text fragment from a HTML body (in .NET) 【发布时间】:2010-11-17 05:44:34 【问题描述】:我有一个用户通过富文本编辑器输入的 html 内容,因此它几乎可以是任何内容(除了那些不应该在 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.Match(textStr, @"^.1,100\b").Value
我的问题是,如何保留换行符?我得到如下输出:
Header 1 Some text hereSome more text here A link here Header 2 Some text hereSome more text
注意到连接的句子了吗?也许有人可以向我展示解决此问题的其他方法。谢谢!
附加信息:我的目的是从一堆 HTML 内容中生成纯文本概要。猜猜这将有助于澄清这个问题。
【问题讨论】:
您是否正在尝试创建一个非常基本的浏览器?我问是因为如果是这样,简单地使用正则表达式(显然)只会让你到目前为止。 @Phairoh 不是浏览器,更像是一个自动概要生成器。 【参考方案1】:我认为解决这个问题的方法是将它视为一个简单的浏览器。创建一个基本的 Tag 类,用一个 InnerHTML 属性和一个虚拟方法 PrintElement 使其抽象。
接下来,为您关心并从基类继承的每个 HTML 标记创建类。从您的示例来看,您最关心的标签是 h1、p、a 和 hr。实现 PrintElement 方法,使其返回一个字符串,该字符串根据 InnerHTML 正确打印出元素(例如 p 类的 PrintElement 将返回“\n[InnerHTML]\n”)。
接下来,构建一个解析器,它将解析您的 HTML 并确定要创建的对象,然后将这些对象添加到队列中(树会更好,但看起来对您的目的来说不是必需的)。
最后,遍历队列,为每个元素调用 PrintElement 方法。
可能比您计划的要多,但它是一个比简单使用正则表达式更强大的解决方案,如果您决定在未来改变主意并想要显示简单的样式,只需返回并修改您的PrintElement 方法。
【讨论】:
这可能是一个更好的解决方案 - 如果您按应有的方式处理 p 和 div 标签(块级元素),那么用新行替换应该会很好地工作。 哇,肯定比我分配的要多得多。如前所述,我的最终目的是提取前 X 个字符并显示为纯文本而不破坏任何单词,并具有相应的换行符作为 HTML 内容在浏览器中的呈现方式。但是感谢 Phairoh 提出了一些我没想到的东西。 +1 :)【参考方案2】:对于信息,使用正则表达式剥离 html 是......充满了微妙的问题。 HTML Agility Pack 可能更健壮,但仍然受到字词的影响:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
string text = doc.DocumentNode.InnerText;
【讨论】:
我试过敏捷包。我不太担心剥离 HTML 标签,因为内容和布局不太花哨。就像你说的那样,话语仍然在流血。【参考方案3】:一种方法是分三步剥离 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 </.*>
【讨论】:
如果段落标签有一个尾随换行符,我必须确保没有引入额外的换行符。我还必须注意任何块元素,如 DIV 和 HR 等。这个列表还在继续。【参考方案4】:好吧,虽然没有理想的解决方案,但我需要关闭它。由于我的应用程序中使用的 HTML 标记非常常见(没有表格、列表等),几乎没有嵌套,所以我所做的是在用户输入后保存 HTML 片段之前预先格式化它们。
删除所有换行符 为所有块标签添加换行前缀(例如 div、p、hr、h1/2/3/4 等)在我提取它们以显示为纯文本之前,使用正则表达式删除 html 标记并保留换行符。几乎没有任何火箭科学,但对我有用。
【讨论】:
以上是关于从 HTML 正文中提取文本片段(在 .NET 中)的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 中提取和清理 HTML 正文文本的最快、最无错误的方法是啥?