ASP.NETを使用して、特定の文字列からHTMLタグを確実に削除するにはどうすればよいですか(つまり、正規表現を使用しない)? PHPのstrip_tags
のようなものを探しています。
<ul><li>Hello</li></ul>
"こんにちは"
私は車輪を再発明しないようにしていますが、私はこれまで私のニーズを満たすものを見つけていません。
文字列からallHTMLタグを削除するだけの場合、正規表現でも同様に確実に機能します。交換:
<[^>]*(>|$)
空の文字列で、グローバルに。その後、文字列を正規化することを忘れないでください:
[\s\r\n]+
単一のスペースを使用して、結果をトリミングします。必要に応じて、HTML文字エンティティを実際の文字に置き換えます。
注:
>
を使用できます。このソリューションは、そのような値に遭遇したときに壊れたマークアップを返します。今すぐHTMLAgilityPackをダウンロードしてください! ;) リンクをダウンロード
これにより、HTMLをロードして解析できます。次に、DOMをナビゲートして、すべての属性の内部値を抽出できます。深刻なことに、最大で約10行のコードが必要になります。これは、最大の無料.netライブラリの1つです。
サンプルを次に示します。
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;
}
Regex.Replace(htmlText, "<.*?>", string.Empty);
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
私はこれをasp.netフォーラムに投稿しましたが、それはまだ最も簡単な解決策の1つであるようです。私はそれが最速または最も効率的であることを保証しませんが、それはかなり信頼できます。 .NETでは、HTML Web Controlオブジェクト自体を使用できます。本当に必要なのは、DIVなどの一時的なHTMLオブジェクトに文字列を挿入し、組み込みの「InnerText」を使用して、タグに含まれていないすべてのテキストを取得することです。簡単なC#の例については、以下を参照してください。
System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;
私はc#で非常に高速なメソッドを記述しました。 CodeProjectの 記事 でホストされています。
その利点は、パフォーマンスの向上の中で、名前付きおよび番号付きのHTMLエンティティ(&amp;
や&203;
など)を置換できること、およびコメントブロックの置換などです。
CodeProjectの関連記事 をお読みください。
ありがとうございました。
HtmlAgilityPackを使用できない場合は、.NETs XMLリーダーがオプションです。ただし、これは適切にフォーマットされたHTMLでは失敗する可能性があるため、常にバックアップとしてregxで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;
}
string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);
Michael Tiptopのソリューションが機能しないことを心配している人のために、これを行う.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;
}
}
using System.Text.RegularExpressions;
string str = Regex.Replace(HttpUtility.HtmlDecode(HTMLString), "<.*?>", string.Empty);
2番目のパラメーター、つまりタグをいくつか保持します。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/
ここで提案されている正規表現ベースのソリューションを見てきましたが、ほとんどの些細な場合を除き、自信を持って私を満たしません。属性の山形括弧は、野生からの不正な形式の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>
、<object>
私たちが望んでいる意味でおそらく彼らが読みやすいコンテンツを含んでいないので!)そこに何をするかはあなたの状況とどこまで行きたいかに依存しますが、HtmlAgilityPackを使用すると、選択したタグをホワイトリストまたはブラックリストに登録することは非常に簡単です。
コンテンツをHTMLページにレンダリングする場合は、XSSの脆弱性と それを防ぐ方法 を理解してください。つまり、HTMLページにレンダリングされるユーザー入力テキストを常にエンコードする(>
は>
などになります)。