Как проверить, что строка не содержит HTML, используя C # - PullRequest
21 голосов
/ 15 октября 2008

Есть ли у кого-нибудь простой и эффективный способ проверить, что строка не содержит HTML? По сути, я хочу проверить, что некоторые поля содержат только простой текст. Я думал о поиске символа <, но его легко использовать в простом тексте. Другим способом может быть создание нового System.Xml.Linq.XElement с помощью: </p>

XElement.Parse("<wrapper>" + MyString + "</wrapper>")

и убедитесь, что XElement не содержит дочерних элементов, но это кажется немного тяжелым для того, что мне нужно.

Ответы [ 7 ]

48 голосов
/ 15 октября 2008

Следующее будет соответствовать любому подходящему набору тегов. то есть это

Regex tagRegex = new Regex(@"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>");

Следующее будет соответствовать любому тегу. то есть (его не нужно закрывать).

Regex tagRegex = new Regex(@"<[^>]+>");

Затем вы можете использовать его так

bool hasTags = tagRegex.IsMatch(myString);
21 голосов
/ 15 октября 2008

Вы можете обеспечить простой текст, кодируя ввод с помощью HttpUtility.HtmlEncode .

Фактически, в зависимости от того, насколько строгой будет проверка, вы можете использовать ее, чтобы определить, содержит ли строка HTML:

bool containsHTML = (myString != HttpUtility.HtmlEncode(myString));
9 голосов
/ 15 октября 2008

Вот, пожалуйста:

using System.Text.RegularExpressions;
private bool ContainsHTML(string CheckString)
{
  return Regex.IsMatch(CheckString, "<(.|\n)*?>");
}

Это самый простой способ, поскольку элементы в скобках вряд ли будут встречаться естественным путем.

7 голосов
/ 15 октября 2008

Я только что попробовал свое решение XElement.Parse. Я создал метод расширения для строкового класса, чтобы можно было легко повторно использовать код:

public static bool ContainsXHTML(this string input)
{
    try
    {
        XElement x = XElement.Parse("<wrapper>" + input + "</wrapper>");
        return !(x.DescendantNodes().Count() == 1 && x.DescendantNodes().First().NodeType == XmlNodeType.Text);
    }
    catch (XmlException ex)
    {
        return true;
    }
}

Одна проблема, которую я обнаружил, заключалась в том, что обычный текст с амперсандом и символами, меньшими, чем символы, вызывают исключение XmlException и указывают, что поле содержит HTML (что неверно). Чтобы это исправить, входная строка, переданная в первую очередь, должна иметь амперсанды и меньше символов, преобразованных в их эквивалентные сущности XHTML. Я написал другой метод расширения, чтобы сделать это:

public static string ConvertXHTMLEntities(this string input)
{
    // Convert all ampersands to the ampersand entity.
    string output = input;
    output = output.Replace("&amp;", "amp_token");
    output = output.Replace("&", "&amp;");
    output = output.Replace("amp_token", "&amp;");

    // Convert less than to the less than entity (without messing up tags).
    output = output.Replace("< ", "&lt; ");
    return output;
}

Теперь я могу взять отправленную пользователем строку и проверить, что она не содержит HTML, используя следующий код:

bool ContainsHTML = UserEnteredString.ConvertXHTMLEntities().ContainsXHTML();

Я не уверен, является ли это пуленепробиваемым, но я думаю, что этого достаточно для моей ситуации.

3 голосов
/ 12 декабря 2014

это также проверяет такие вещи, как
закрытые теги с необязательным пробелом. список не содержит новых тегов html5.

internal static class HtmlExts
{
    public static bool containsHtmlTag(this string text, string tag)
    {
        var pattern = @"<\s*" + tag + @"\s*\/?>";
        return Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);
    }

    public static bool containsHtmlTags(this string text, string tags)
    {
        var ba = tags.Split('|').Select(x => new {tag = x, hastag = text.containsHtmlTag(x)}).Where(x => x.hastag);

        return ba.Count() > 0;
    }

    public static bool containsHtmlTags(this string text)
    {
        return
            text.containsHtmlTags(
                "a|abbr|acronym|address|area|b|base|bdo|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|DOCTYPE|dt|em|fieldset|form|h1|h2|h3|h4|h5|h6|head|html|hr|i|img|input|ins|kbd|label|legend|li|link|map|meta|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var");
    }
}
2 голосов
/ 15 октября 2008

Угловые скобки могут быть не единственной вашей задачей. Другие символы также могут быть потенциально вредными для внедрения скриптов. Например, общий двойной дефис "-", который также можно использовать в SQL-инъекции. И есть другие.

На странице ASP.Net, если validateRequest = true в machine.config, web.config или в директиве page, пользователь получит страницу с сообщением об ошибке: обнаружен тег HTML или другие потенциальные атаки с использованием скриптов. Вы, вероятно, хотите избежать этого и предоставить более элегантный и менее страшный интерфейс.

Вы можете проверить открывающий и закрывающий теги <> с помощью регулярного выражения и разрешить текст, если только один из них встречается. Разрешить <или>, но не <с последующим текстом и затем> в указанном порядке.

Вы можете разрешить использование угловых скобок и HtmlEncode для сохранения текста при сохранении данных.

0 голосов
/ 12 марта 2011

Остерегайтесь при использовании метода HttpUtility.HtmlEncode, упомянутого выше. Если вы проверяете некоторый текст со специальными символами, но не HTML, он будет оцениваться неправильно. Может быть, поэтому J и использовал «... в зависимости от того, насколько строгим будет чек ...»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...