使用ASP.NET,如何可靠地从给定字符串中剥离HTML标记(即不使用正则表达式)?我正在寻找像PHP strip_tags
。
<ul><li>Hello</li></ul>
“你好”
我试图不重新发明轮子,但到目前为止我还没有找到满足我需求的东西。
答案 0 :(得分:107)
如果它只是从字符串中剥离所有 HTML标记,那么这也适用于正则表达式。替换:
<[^>]*(>|$)
全局使用空字符串。不要忘记之后规范化字符串,替换:
[\s\r\n]+
使用单个空格,并修剪结果。 (可选)将任何HTML字符实体替换为实际字符。
注意:
>
。遇到此类值时,此解决方案将返回损坏的标记。答案 1 :(得分:72)
立即下载HTMLAgilityPack! ;)Download LInk
这允许您加载和解析HTML。然后,您可以导航DOM并提取所有属性的内部值。说真的,最多需要大约10行代码。它是最好的免费.net库之一。
以下是一个示例:
string htmlContents = new System.IO.StreamReader(resultsStream,Encoding.UTF8,true).ReadToEnd();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(htmlContents);
if (doc == null) return null;
string output = "";
foreach (var node in doc.DocumentNode.ChildNodes)
{
output += node.InnerText;
}
答案 2 :(得分:64)
Regex.Replace(htmlText, "<.*?>", string.Empty);
答案 3 :(得分:11)
protected string StripHtml(string Txt)
{
return Regex.Replace(Txt, "<(.|\\n)*?>", string.Empty);
}
Protected Function StripHtml(Txt as String) as String
Return Regex.Replace(Txt, "<(.|\n)*?>", String.Empty)
End Function
答案 4 :(得分:6)
我已经在asp.net论坛上发布了它,它似乎仍然是那里最简单的解决方案之一。我不保证它是最快或最有效的,但它非常可靠。 在.NET中,您可以使用HTML Web Control对象本身。您真正需要做的就是将您的字符串插入到临时HTML对象(如DIV)中,然后使用内置的“InnerText”来获取标记中未包含的所有文本。请参阅下面的简单C#示例:
System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;
答案 5 :(得分:5)
我在c#中编写了一个非常快速的方法,它击败了正则表达式。它在CodeProject上的an article中托管。
它的优点是,在更好的性能中,能够替换命名和编号的HTML实体(如&amp;
和&203;
)和注释块替换等等。
请阅读related article on CodeProject。
谢谢。
答案 6 :(得分:4)
对于那些不能使用HtmlAgilityPack的人来说,.NETs XML阅读器是一种选择。这可能会在格式良好的HTML上失败,但总是添加一个catch作为备份。请注意,这并不快,但它确实为老学校调试提供了一个很好的机会。
public static string RemoveHTMLTags(string content)
{
var cleaned = string.Empty;
try
{
StringBuilder textOnly = new StringBuilder();
using (var reader = XmlNodeReader.Create(new System.IO.StringReader("<xml>" + content + "</xml>")))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
textOnly.Append(reader.ReadContentAsString());
}
}
cleaned = textOnly.ToString();
}
catch
{
//A tag is probably not closed. fallback to regex string clean.
string textOnly = string.Empty;
Regex tagRemove = new Regex(@"<[^>]*(>|$)");
Regex compressSpaces = new Regex(@"[\s\r\n]+");
textOnly = tagRemove.Replace(content, string.Empty);
textOnly = compressSpaces.Replace(textOnly, " ");
cleaned = textOnly;
}
return cleaned;
}
答案 7 :(得分:3)
string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);
答案 8 :(得分:1)
对于那些抱怨迈克尔蒂普顿的解决方案不起作用的人来说,这是.Net4 +的做法:
public static string StripTags(this string markup)
{
try
{
StringReader sr = new StringReader(markup);
XPathDocument doc;
using (XmlReader xr = XmlReader.Create(sr,
new XmlReaderSettings()
{
ConformanceLevel = ConformanceLevel.Fragment
// for multiple roots
}))
{
doc = new XPathDocument(xr);
}
return doc.CreateNavigator().Value; // .Value is similar to .InnerText of
// XmlDocument or JavaScript's innerText
}
catch
{
return string.Empty;
}
}
答案 9 :(得分:0)
我已经看过这里建议的基于正则表达式的解决方案,除了最琐碎的案例外,他们没有任何信心。属性中的尖括号是破坏所需的全部,更不用说来自野外的恶意形式的HTML。那些像&
这样的实体呢?如果要将HTML转换为纯文本,还需要解码实体。
所以我建议采用以下方法。
使用HtmlAgilityPack,此扩展方法可以有效地从html片段中删除所有HTML标记。还解码像&
这样的HTML实体。仅返回内部文本项,每个文本项之间都有一个新行。
public static string RemoveHtmlTags(this string html)
{
if (String.IsNullOrEmpty(html))
return html;
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
if (doc.DocumentNode == null || doc.DocumentNode.ChildNodes == null)
{
return WebUtility.HtmlDecode(html);
}
var sb = new StringBuilder();
var i = 0;
foreach (var node in doc.DocumentNode.ChildNodes)
{
var text = node.InnerText.SafeTrim();
if (!String.IsNullOrEmpty(text))
{
sb.Append(text);
if (i < doc.DocumentNode.ChildNodes.Count - 1)
{
sb.Append(Environment.NewLine);
}
}
i++;
}
var result = sb.ToString();
return WebUtility.HtmlDecode(result);
}
public static string SafeTrim(this string str)
{
if (str == null)
return null;
return str.Trim();
}
如果您真的很认真,那么您也想忽略某些HTML标记的内容(<script>
,<style>
,<svg>
,<head>
,{ {1}}浮现在脑海中!)因为它们可能并不包含我们所追求的可读内容。你在那里做什么将取决于你的情况和你想走多远,但使用HtmlAgilityPack将所选标签列入白名单或黑名单将是非常简单的。
如果要将内容呈现回HTML页面,请确保您了解XSS漏洞&amp; how to prevent it - 即始终对任何用户输入的文字进行编码,这些文字会被渲染回HTML页面(<object>
变为>
等)。
答案 10 :(得分:0)
对于第二个参数,即。保留一些标签,你可能需要使用HTMLagilityPack这样的代码:
public string StripTags(HtmlNode documentNode, IList keepTags)
{
var result = new StringBuilder();
foreach (var childNode in documentNode.ChildNodes)
{
if (childNode.Name.ToLower() == "#text")
{
result.Append(childNode.InnerText);
}
else
{
if (!keepTags.Contains(childNode.Name.ToLower()))
{
result.Append(StripTags(childNode, keepTags));
}
else
{
result.Append(childNode.OuterHtml.Replace(childNode.InnerHtml, StripTags(childNode, keepTags)));
}
}
}
return result.ToString();
}
此页面上的更多说明:http://nalgorithm.com/2015/11/20/strip-html-tags-of-an-html-in-c-strip_html-php-equivalent/
答案 11 :(得分:0)
using System.Text.RegularExpressions;
string str = Regex.Replace(HttpUtility.HtmlDecode(HTMLString), "<.*?>", string.Empty);
答案 12 :(得分:0)
您也可以使用AngleSharp来完成此操作,它可以替代HtmlAgilityPack(不是说HAP不好)。比起HAP,从HTML源中提取文本要容易得多。
var parser = new HtmlParser();
var htmlDocument = parser.ParseDocument(source);
var text = htmlDocument.Body.Text();
您可以看看key features部分,他们在其中提出了比HAP“更好”的理由。我认为,在大多数情况下,这可能对当前问题有些大材小用,但仍然是一个有趣的选择。
答案 13 :(得分:-3)
只需使用string.StripHTML();