Jak mogę usunąć znaczniki HTML z ciągu znaków w ASP.NET?

Za pomocą ASP.NET, w jaki sposób mogę niezawodnie usunąć znaczniki HTML z danego ciągu znaków (tzn. nie używać regex)? Szukam czegoś takiego jak PHP strip_tags.

Przykład:

<ul><li>Hello</li></ul>

Wyjście:

"Hello"

Staram się nie odkrywać koła na nowo, ale jak dotąd nie znalazłem niczego, co zaspokoi moje potrzeby.
Author: Rami Shareef, 2009-04-24

13 answers

Jeśli po prostu usuwa Wszystkie znaczniki HTML z ciągu znaków, działa to niezawodnie również z regex. "Replace": {]}

<[^>]*(>|$)

Z pustym łańcuchem, globalnie. Nie zapomnij potem znormalizować ciągu znaków, zastępując:

[\s\r\n]+

Z pojedynczą spacją i przycinanie wyniku. Opcjonalnie zastąp dowolne encje znaków HTML z powrotem na rzeczywiste znaki.

Uwaga :

  1. istnieje ograniczenie: HTML i XML pozwalają > w wartościach atrybutów. To rozwiązanie zwróci uszkodzone znaczniki, gdy napotkasz takie wartości.
  2. rozwiązanie jest technicznie bezpieczne, jak w: wynik nigdy nie będzie zawierał niczego, co mogłoby być użyte do tworzenia skryptów krzyżowych lub łamania układu strony. To nie jest zbyt czyste.
  3. Jak w przypadku wszystkich rzeczy HTML i regex:
    użyj odpowiedniego parsera, jeśli musisz to zrobić poprawnie w każdych okolicznościach.
 101
Author: Tomalak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-23 03:11:49

Pobierz HTMLAgilityPack, teraz! ;) Download LInk

To pozwala na ładowanie i analizowanie HTML. Następnie możesz poruszać się po DOM i wyodrębnić wewnętrzne wartości wszystkich atrybutów. Poważnie, zajmie ci to maksymalnie około 10 linii kodu. Jest to jedna z największych darmowych bibliotek.NET.

Oto przykład:

            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;
            }
 70
Author: Serapth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-16 15:25:56
Regex.Replace(htmlText, "<.*?>", string.Empty);
 60
Author: user95144,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-13 22:51:46
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
 10
Author: meramez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-22 09:52:26

Zamieściłem to na asp.net Forum, i nadal wydaje się być jednym z najprostszych rozwiązań tam. Nie gwarantuję, że jest najszybszy lub najbardziej wydajny, ale jest dość niezawodny. W. NET możesz używać samych obiektów HTML Web Control. Wszystko, co naprawdę musisz zrobić, to wstawić swój ciąg do tymczasowego obiektu HTML, takiego jak DIV, a następnie użyj wbudowanego "InnerText", aby pobrać cały tekst, który nie jest zawarty w tagach. Zobacz poniżej prosty przykład C#:


System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;
 6
Author: Michael Tipton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-05 17:16:51

Napisałem dość szybką metodę w c# , która bije piekło z Regex. Jest on umieszczony w artykule {[4] } na CodeProject.

Jego zaletami są m.in. lepsza wydajność, możliwość zastępowania nazwanych i ponumerowanych encji HTML (takich jak &amp;amp; i &203;) oraz wymiana bloków komentarzy i wiele innych.

Proszę przeczytać powiązany artykuł na CodeProject .

Dziękuję.
 5
Author: Andrei Rînea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-08 15:50:47

Dla tych z Was, którzy nie mogą korzystać z Htmlagilipack, .NETs XML reader jest opcją. To może się nie udać w dobrze sformatowanym HTML, więc zawsze dodaj haczyk z regx jako kopię zapasową. Zauważ, że nie jest to szybkie, ale zapewnia miłą okazję do oldschoolowego debugowania.

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;
    }
 4
Author: Bucket,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-05 11:55:38
string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);
 3
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-08 15:50:21

Dla tych, którzy narzekają na rozwiązanie Michaela Tiptop nie działa, oto sposób. 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;
    }
}
 1
Author: Annie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-18 01:09:09

Przyjrzałem się rozwiązaniom opartym na Regex sugerowanym tutaj, i nie napełniają mnie one pewnością, z wyjątkiem najbardziej błahych przypadków. Wspornik kątowy w atrybutie to wszystko, czego potrzeba, aby złamać, nie mówiąc już o mal-formmed HTML od dzikiego. A co z bytami takimi jak &amp;? Jeśli chcesz przekonwertować HTML na zwykły tekst, musisz również dekodować encje.

Więc proponuję metodę poniżej.

Używając HtmlAgilityPack , ta metoda rozszerzenia skutecznie usuwa wszystkie Znaczniki HTML z fragmentu html. Dekoduje również encje HTML, takie jak &amp;. Zwraca tylko wewnętrzne elementy tekstu, z nową linią między każdym elementem tekstu.

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

Jeśli jesteś naprawdę poważny, chcesz zignorować zawartość niektórych tagów HTML(<script>, <style>, <svg>, <head>, <object> chodź do głowy!), ponieważ prawdopodobnie nie zawierają treści czytelnych w sensie, w jakim jesteśmy po. To, co tam zrobisz, będzie zależeć od twoich okoliczności i tego, jak daleko chcesz się posunąć, ale używając HtmlAgilityPack, to być dość trywialne do białej lub czarnej listy wybranych tagów.

Jeśli renderujesz zawartość z powrotem na stronę HTML, upewnij się, że rozumiesz lukę XSS & jak jej zapobiec - tzn. zawsze koduj każdy wprowadzony przez użytkownika tekst, który zostanie renderowany z powrotem na stronę HTML (> staje się &gt; itd.).

 0
Author: saille,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 23:49:20

Dla drugiego parametru, tzn. zachowaj kilka tagów, możesz potrzebować kodu takiego jak ten, używając 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();
    }

Więcej wyjaśnień na tej stronie: http://nalgorithm.com/2015/11/20/strip-html-tags-of-an-html-in-c-strip_html-php-equivalent/

 0
Author: Yuksel Daskin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-07 09:00:55
using System.Text.RegularExpressions;

string str = Regex.Replace(HttpUtility.HtmlDecode(HTMLString), "<.*?>", string.Empty);
 0
Author: Karan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 06:58:38

Po prostu użyj string.StripHTML();

 -3
Author: user3638478,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-14 21:44:11