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



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



пример:



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



выход:



"Привет"



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

615   13  

13 ответов:

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

<[^>]*(>|$)

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

[\s\r\n]+

С одним пробелом и обрезкой результата. При необходимости замените любые объекты символов HTML обратно на фактические символы.

Примечание:

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

перейти скачать HTMLAgilityPack, сейчас! ;)Ссылка Для Скачивания

Это позволяет загружать и анализировать 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;
            }
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 форумы, и это все еще кажется одним из самых простых решений там. Я не буду гарантировать, что это самый быстрый или самый эффективный, но это довольно надежно. В .Net вы можете использовать веб-элемент управления HTML-объектов. Все, что вам действительно нужно сделать, это вставить строку во временный HTML-объект, такой как DIV, а затем использовать встроенный "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;amp; и &203;) и замена блоков комментариев и многое другое.

пожалуйста, читайте связанная статья о CodeProject.

спасибо.

для тех из вас, кто не может использовать HtmlAgilityPack, .NETs XML reader-это опция. Это может не сработать на хорошо отформатированном HTML, хотя всегда добавляйте улов с 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;
    }
string result = Regex.Replace(anytext, @"<(.|\n)*?>", string.Empty);

для тех, кто жалуется на то, что решение Майкла Типтопа не работает, вот способ. 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;
    }
}

Я посмотрел на решения на основе регулярных выражений, предложенные здесь, и они не наполняют меня уверенностью, за исключением самых тривиальных случаев. Угловая скобка в атрибуте-это все, что нужно, чтобы сломать, не говоря уже о mal-formmed 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; etc).

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

using System.Text.RegularExpressions;

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

просто использовать string.StripHTML();

Comments

    Ничего не найдено.