Entfernen Sie HTML-Tags aus der Zeichenfolge, einschließlich & nbsp in C #

83

Wie kann ich alle HTML-Tags einschließlich & nbsp mit Regex in C # entfernen? Meine Saite sieht aus wie

  "<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>"
rampuriyaaa
quelle
9
Verwenden Sie keinen regulären Ausdruck, sondern lesen Sie das HTML Agility Pack. stackoverflow.com/questions/846994/how-to-use-html-agility-pack
Tim
Vielen Dank, Tim, aber die Anwendung ist ziemlich groß und intakt. Das Hinzufügen oder Herunterladen eines HTML-Agility-Packs funktioniert nicht.
Rampuriyaaa

Antworten:

195

Wenn Sie keine HTML-Parser-orientierte Lösung zum Herausfiltern der Tags verwenden können, finden Sie hier einen einfachen regulären Ausdruck dafür.

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

Idealerweise sollten Sie einen weiteren Durchlauf durch einen Regex-Filter durchführen, der mehrere Leerzeichen als berücksichtigt

string noHTMLNormalised = Regex.Replace(noHTML, @"\s{2,}", " ");
Ravi Thapliyal
quelle
Ich habe dies noch nicht so oft getestet, wie ich es brauchen werde, aber es hat besser funktioniert, als ich erwartet hatte. Ich werde die Methode, die ich unten geschrieben habe, veröffentlichen.
Don Rolling
Ein fauler Match ( <[^>]+?>gemäß @David S.) könnte dies ein bisschen schneller machen, aber diese Lösung wurde nur in einem Live-Projekt verwendet - sehr glücklich +1 :)
Gone Coding
Regex.Replace (inputHTML, @ "<[^>] +> | & nbsp | \ n;", "") .Trim (); \ n wird nicht entfernt
Mahesh Malpani
3
Ich würde empfehlen, ein Leerzeichen anstelle einer leeren Zeichenfolge Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", " ")
hinzuzufügen.
2
@Tauseef Wenn Sie beim ersten Ersetzungsaufruf ein Leerzeichen verwenden, bleiben möglicherweise Leerzeichen übrig, in denen in der ursprünglichen Eingabe keine Leerzeichen vorhanden waren. Angenommen, Sie erhalten Sound<b>Cloud</b>als Eingabe; Sie werden am Ende haben, Sound Cloudwährend es hätte entfernt werden sollen, SoundCloudweil es so in HTML angezeigt wird.
Ravi Thapliyal
31

Ich habe den Code von @Ravi Thapliyal genommen und eine Methode erstellt: Es ist einfach und bereinigt möglicherweise nicht alles, aber bisher macht es das, wofür ich es brauche.

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

Ich benutze diese Funktion seit einer Weile. Entfernt so ziemlich jedes unordentliche HTML, das Sie darauf werfen können, und lässt den Text intakt.

        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();
        }
David S.
quelle
Nur zur Bestätigung: Die SingleSpacedTrim () -Funktion macht dasselbe wie die Zeichenfolge noHTMLNormalised = Regex.Replace (noHTML, @ "\ s {2,}", ""); von Ravi Thapliyals Antwort?
Jimmy
@ Jimmy Soweit ich sehen kann, fängt dieser reguläre Ausdruck keine einzelnen Tabulatoren oder Zeilenumbrüche ab, wie dies bei SingleSpacedTrim () der Fall ist. Dies könnte jedoch ein wünschenswerter Effekt sein. In diesem Fall entfernen Sie die Fälle einfach nach Bedarf.
David S.
Schön, aber es scheint auch einfache und doppelte Anführungszeichen durch Leerzeichen zu ersetzen, obwohl sie nicht in der Liste " notOkCharacter " enthalten sind, oder fehlt mir dort etwas? Wird dieser Teil der Decodierungs- / Codierungsmethoden am Anfang aufgerufen? Was wäre notwendig, um diese Charaktere intakt zu halten?
VM370
4
var noHtml = Regex.Replace(inputHTML, @"<[^>]*(>|$)|&nbsp;|&zwnj;|&raquo;|&laquo;", string.Empty).Trim();
MRP
quelle
1

Ich habe den Code von @RaviThapliyal & @Don Rolling verwendet, aber eine kleine Änderung vorgenommen. Da wir die & nbsp durch eine leere Zeichenfolge ersetzen, stattdessen aber & nbsp durch Leerzeichen ersetzt werden sollten, wurde ein zusätzlicher Schritt hinzugefügt. Es hat bei mir wie ein Zauber funktioniert.

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;
}

Verwendet & nbps ohne Semikolon, da es vom Stapelüberlauf formatiert wurde.

Sabique A Khan
quelle
0

Dies:

(<.+?> | &nbsp;)

passt zu jedem Tag oder &nbsp;

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

dann x = hello

Jonesopolis
quelle
0

Das Bereinigen eines HTML-Dokuments ist mit vielen kniffligen Dingen verbunden. Dieses Paket kann hilfreich sein: https://github.com/mganss/HtmlSanitizer

Ehsan88
quelle
Ich denke, es ist mehr gegen XSS-Angriffe als um HTML zu normalisieren
Revious
1
@Revious Ich denke du hast recht. Vielleicht hat meine Antwort nicht viel mit der Frage des OP zu tun, da sie den Zweck des Entfernens von HTML-Tags nicht erwähnt haben. Wenn der Zweck jedoch darin besteht, Angriffe zu verhindern, wie dies in vielen Fällen der Fall ist, kann die Verwendung eines bereits entwickelten Desinfektionsmittels ein besserer Ansatz sein. Übrigens weiß ich nicht, was die Normalisierung von HTML bedeutet .
Ehsan88
0

HTML ist in seiner Grundform nur XML. Sie können Ihren Text in einem XmlDocument-Objekt analysieren und im Stammelement InnerText aufrufen, um den Text zu extrahieren. Dadurch werden alle HTML-Tages in beliebiger Form entfernt und Sonderzeichen wie & lt; & nbsp; alles auf einmal.

nivs1978
quelle