Как удалить теги HTML из строки в ASP.NET?

Используя ASP.NET, как я могу надежно отделить HTML-теги от заданной строки (т.е. не использовать регулярное выражение)? Я ищу что-то вроде PHP strip_tags.

Пример:

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

Вывод:

"Hello"

Я стараюсь не изобретать колесо, но я не нашел ничего, что отвечало моим потребностям.

Ответ 1

Если он просто удаляет все теги HTML из строки, это также надежно работает с регулярным выражением. Заменить:

<[^>]*(>|$)

с пустой строкой, глобально. Не забудьте впоследствии нормализовать строку, заменив:

[\s\r\n]+

с одним пробелом и обрезкой результата. Опционально замените любые элементы символа HTML на фактические символы.

Примечание:

  • Существует ограничение: HTML и XML позволяют > в значениях атрибутов. Это решение вернет поврежденную разметку при достижении таких значений.
  • Решение технически безопасно, так как в: Результат никогда не будет содержать ничего, что можно было бы использовать для межсайтового скриптинга или для разбивки макета страницы. Это просто не очень чисто.
  • Как со всеми вещами HTML и регулярное выражение:
    Используйте правильный парсер, если вы должны получить его правильно при любых обстоятельствах.

Ответ 2

Go скачать HTMLAgilityPack, сейчас!;) Загрузить 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;
            }

Ответ 3

Regex.Replace(htmlText, "<.*?>", string.Empty);

Ответ 4

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

Ответ 5

Я разместил это на форумах asp.net, и это все еще кажется одним из самых простых решений. Я не буду гарантировать его самым быстрым или эффективным, но он довольно надежный. В .NET вы можете сами использовать объекты HTML Web Control. Все, что вам действительно нужно сделать, это вставить вашу строку во временный объект HTML, такой как DIV, а затем использовать встроенный "InnerText", чтобы захватить весь текст, который не содержится в тегах. Ниже приведен простой пример С#:


System.Web.UI.HtmlControls.HtmlGenericControl htmlDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
htmlDiv.InnerHtml = htmlString;
String plainText = htmlDiv.InnerText;

Ответ 6

Я написал довольно быстрый метод в С#, который бьет ад из Regex. Он размещен в статье в CodeProject.

Его преимущества заключаются в том, что среди лучшей производительности есть возможность заменить именованные и пронумерованные HTML-объекты (те, что похожи на &amp;amp; и &203;), и заменить блоки комментариев и многое другое.

Пожалуйста, прочитайте статью .

Спасибо.

Ответ 7

string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);

Ответ 8

Для тех из вас, кто не может использовать HtmlAgilityPack,.NET XML-ридер является опцией. Это может завершиться неудачно на хорошо отформатированном HTML, хотя всегда добавляйте catch с regx в качестве резервной копии. Обратите внимание, что это НЕ быстро, но это дает хорошую возможность для старой школы пройти через отладку.

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

Ответ 9

Для тех, кто усложняет решение 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 innerText
    }
    catch
    {
        return string.Empty;
    }
}

Ответ 10

using System.Text.RegularExpressions;

string str = Regex.Replace(HttpUtility.HtmlDecode(HTMLString), "<.*?>", string.Empty);

Ответ 11

Я рассмотрел предлагаемые здесь решения на основе Regex, и они не наполняют меня какой-либо уверенностью, кроме самых тривиальных случаев. Угол скобки в атрибуте - это все, что нужно, чтобы сломать, не говоря уже о некорректно сформированном HTML из дикой природы. А как насчет объектов вроде &amp;? Если вы хотите преобразовать HTML в обычный текст, вам также нужно декодировать объекты.

Итак, предлагаю метод ниже.

Используя HtmlAgilityPack, этот метод расширения эффективно удаляет все теги HTML из html-фрагмента. Также декодирует объекты HTML, такие как &amp;. Возвращает только внутренние текстовые элементы, с новой строкой между каждым текстовым элементом.

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-страницу (> становится &gt; и т.д.).

Ответ 12

Для второго параметра, т.е. сохраните некоторые теги, вам может понадобиться некоторый код, подобный этому, используя 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/

Ответ 13

Просто используйте string.StripHTML();