C#の&nbspを含む文字列からHTMLタグを削除します


83

C#で正規表現を使用して&nbspを含むすべてのHTMLタグを削除するにはどうすればよいですか。私の文字列は

  "<div>hello</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div>"

9
正規表現を使用しないでください。HTMLAgilityPackを確認してください。stackoverflow.com/questions/846994/how-to-use-html-agility-pack
Tim

Timに感謝しますが、アプリケーションは非常に大きく、そのままで、htmlアジリティパックを追加またはダウンロードしても機能しません。
rpmuriyaaa 2013年

回答:


196

HTMLパーサー指向のソリューションを使用してタグを除外できない場合は、次の簡単な正規表現を使用してください。

string noHTML = Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", "").Trim();

理想的には、複数のスペースを処理する正規表現フィルターをもう一度通過する必要があります。

string noHTMLNormalised = Regex.Replace(noHTML, @"\s{2,}", " ");

必要なだけこれをテストしていませんが、予想よりもうまく機能しました。以下に書いた方法を投稿します。
ドンローリング

怠惰な試合(<[^>]+?>@David S.による)はこれを少し速くするかもしれませんが、ライブプロジェクトでこのソリューションを使用しただけです-非常に幸せです+1 :)
Gone Coding

Regex.Replace(inputHTML、@ "<[^>] +> |&nbsp | \ n;"、 "").Trim(); \ n削除されません
Mahesh Malpani 2015

3
空の文字列ではなくスペースを広告することをお勧めします。とにかく余分なスペースをRegex.Replace(inputHTML, @"<[^>]+>|&nbsp;", " ")
見つけてい

2
@Tauseef最初のreplace呼び出しでスペースを使用すると、元の入力にスペースがなかった場所にスペースが残る可能性があります。Sound<b>Cloud</b>入力として受け取ったとしましょう。それがHTMLで表示される方法であるため、Sound Cloud削除されるべきである間に終了しSoundCloudます。
Ravi Thapliyal 2015

31

@Ravi Thapliyalのコードを使用して、メソッドを作成しました。これは単純で、すべてをクリーンアップできるわけではないかもしれませんが、これまでのところ、必要な処理を実行しています。

public static string ScrubHtml(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>|&nbsp;", "").Trim();
    var step2 = Regex.Replace(step1, @"\s{2,}", " ");
    return step2;
}

16

私はこの機能をしばらく使っています。あなたがそれに投げることができるほとんどすべての厄介なhtmlを削除し、テキストをそのまま残します。

        private static readonly Regex _tags_ = new Regex(@"<[^>]+?>", RegexOptions.Multiline | RegexOptions.Compiled);

        //add characters that are should not be removed to this regex
        private static readonly Regex _notOkCharacter_ = new Regex(@"[^\w;&#@.:/\\?=|%!() -]", RegexOptions.Compiled);

        public static String UnHtml(String html)
        {
            html = HttpUtility.UrlDecode(html);
            html = HttpUtility.HtmlDecode(html);

            html = RemoveTag(html, "<!--", "-->");
            html = RemoveTag(html, "<script", "</script>");
            html = RemoveTag(html, "<style", "</style>");

            //replace matches of these regexes with space
            html = _tags_.Replace(html, " ");
            html = _notOkCharacter_.Replace(html, " ");
            html = SingleSpacedTrim(html);

            return html;
        }

        private static String RemoveTag(String html, String startTag, String endTag)
        {
            Boolean bAgain;
            do
            {
                bAgain = false;
                Int32 startTagPos = html.IndexOf(startTag, 0, StringComparison.CurrentCultureIgnoreCase);
                if (startTagPos < 0)
                    continue;
                Int32 endTagPos = html.IndexOf(endTag, startTagPos + 1, StringComparison.CurrentCultureIgnoreCase);
                if (endTagPos <= startTagPos)
                    continue;
                html = html.Remove(startTagPos, endTagPos - startTagPos + endTag.Length);
                bAgain = true;
            } while (bAgain);
            return html;
        }

        private static String SingleSpacedTrim(String inString)
        {
            StringBuilder sb = new StringBuilder();
            Boolean inBlanks = false;
            foreach (Char c in inString)
            {
                switch (c)
                {
                    case '\r':
                    case '\n':
                    case '\t':
                    case ' ':
                        if (!inBlanks)
                        {
                            inBlanks = true;
                            sb.Append(' ');
                        }   
                        continue;
                    default:
                        inBlanks = false;
                        sb.Append(c);
                        break;
                }
            }
            return sb.ToString().Trim();
        }

確認のために:SingleSpacedTrim()関数は、文字列noHTMLNormalised = Regex.Replace(noHTML、@ "\ s {2、}"、 "");と同じことを行います。Ravi Thapliyalの答えから?
ジミー

@Jimmy私が見る限り、その正規表現はSingleSpacedTrim()のように単一のタブや改行をキャッチしません。ただし、これは望ましい効果である可能性があります。その場合は、必要に応じてケースを削除してください。
David S.

いいですが、一重引用符と二重引用符も「notOkCharacter」リストにないのに空白に置き換えられているようです。それとも何かが足りないのでしょうか。デコード/エンコード会議のこの部分は最初に呼び出されますか?これらのキャラクターを無傷に保つために何が必要でしょうか?
vm370 2016

4
var noHtml = Regex.Replace(inputHTML, @"<[^>]*(>|$)|&nbsp;|&zwnj;|&raquo;|&laquo;", string.Empty).Trim();

1

@RaviThapliyalと@DonRollingのコードを使用しましたが、少し変更を加えました。&nbspを空の文字列に置き換えていますが、代わりに&nbspをスペースに置き換える必要があるため、追加の手順を追加しました。それは私にとって魅力のように働いた。

public static string FormatString(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>", "").Trim();
    var step2 = Regex.Replace(step1, @"&nbsp;", " ");
    var step3 = Regex.Replace(step2, @"\s{2,}", " ");
    return step3;
}

スタックオーバーフローによってフォーマットされていたため、セミコロンなしで&nbpsを使用しました。


0

この:

(<.+?> | &nbsp;)

任意のタグと一致するか &nbsp;

string regex = @"(<.+?>|&nbsp;)";
var x = Regex.Replace(originalString, regex, "").Trim();

次にx = hello


0

Htmlドキュメントのサニタイズには、多くの注意が必要です。このパッケージはおそらく助けになります:https//github.com/mganss/HtmlSanitizer


htmlを正規化するよりもXSS攻撃の方が多いと思います
Revious 2013

1
@Reviousあなたは正しいと思います。おそらく私の答えは、HTMLタグを削除する目的について言及していなかったため、OPの質問とはあまり関係がありません。しかし、多くの場合のように、目的が攻撃を防ぐことである場合は、すでに開発された消毒剤を使用する方が良いアプローチかもしれません。ところで、私はhtml正規化することの意味が何であるかについての知識がありません。
ehsan 8819

0

HTMLは、基本的な形式ではXMLだけです。XmlDocumentオブジェクトでテキストを解析し、ルート要素でInnerTextを呼び出してテキストを抽出できます。これにより、あらゆる形式のすべてのHTMLタグが削除され、&lt;などの特殊文字も処理されます。&nbsp; オールインワンゴー。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.