Использование регулярных выражений C # для удаления тегов HTML - PullRequest
136 голосов
/ 25 апреля 2009

Как использовать регулярное выражение C # для замены / удаления всех тегов HTML, включая угловые скобки? Может кто-нибудь помочь мне с кодом?

Ответы [ 10 ]

146 голосов
/ 25 апреля 2009

Как часто говорилось ранее, вы не должны использовать регулярные выражения для обработки документов XML или HTML. Они не очень хорошо работают с документами HTML и XML, потому что нет способа выразить вложенные структуры в общем виде.

Вы можете использовать следующее.

String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);

Это будет работать в большинстве случаев, но будут случаи (например, CDATA, содержащие угловые скобки), где это не будет работать должным образом.

78 голосов
/ 25 апреля 2009

Правильный ответ: не делайте этого, используйте HTML Agility Pack .

Отредактировано, чтобы добавить:

Чтобы бесстыдно украсть из комментария ниже Джесси и избежать обвинений в неадекватном ответе на этот вопрос после всего этого времени, вот простой надежный фрагмент, использующий пакет Agility HTML, который работает даже с самыми несовершенно сформированными, капризными частями HTML:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Properties.Resources.HtmlContents);
var text = doc.DocumentNode.SelectNodes("//body//text()").Select(node => node.InnerText);
StringBuilder output = new StringBuilder();
foreach (string line in text)
{
   output.AppendLine(line);
}
string textOnly = HttpUtility.HtmlDecode(output.ToString());

Существует очень мало оправданных случаев использования регулярного выражения для синтаксического анализа HTML, так как HTML не может быть правильно проанализирован без понимания контекста, которое очень трудно обеспечить даже в нетрадиционном движке регулярных выражений. Вы можете получить часть пути с RegEx, но вам нужно будет выполнить ручную проверку.

Html Agility Pack может предоставить вам надежное решение, которое уменьшит необходимость вручную исправлять аберрации, которые могут возникнуть в результате наивного обращения с HTML как с контекстно-свободной грамматикой.

Регулярное выражение может дать вам в основном то, что вы хотите, большую часть времени, но оно не сработает в очень распространенных случаях. Если вы можете найти лучший / более быстрый анализатор, чем HTML Agility Pack, сделайте это, но, пожалуйста, не подвергайте мир большему количеству взломанных HTML-атак.

37 голосов
/ 25 апреля 2009

Вопрос слишком широкий, чтобы на него можно было ответить однозначно. Вы говорите об удалении всех тегов из реального HTML-документа, например веб-страницы? Если это так, вам придется:

  • удалить объявление <! DOCTYPE или <? Xml пролог, если они существуют </li>
  • удалить все комментарии SGML
  • удалить весь элемент HEAD
  • удалить все элементы SCRIPT и STYLE
  • делать Grabthar-знает-что с элементами FORM и TABLE
  • удалить оставшиеся теги
  • удалить последовательности <! [CDATA [и]]> из разделов CDATA, но оставить их содержимое в покое

Это только у меня в голове - я уверен, что это еще не все. Сделав все это, вы получите слова, предложения и абзацы, собранные вместе в некоторых местах, и большие куски бесполезного пробела в других.

Но, если вы работаете только с фрагментом и можете просто удалить все теги, вот регулярное выражение, которое я бы использовал:

@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"

Сопоставление строк с одинарными и двойными кавычками в их собственных альтернативах достаточно для решения проблемы угловых скобок в значениях атрибутов. Я не вижу необходимости явно сопоставлять имена атрибутов и другие вещи внутри тега, как это делает регулярное выражение в ответе Райана; первая альтернатива обрабатывает все это.

Если вам интересны эти (?>...) конструкции, то они атомные группы . Они делают регулярные выражения немного более эффективными, но, что более важно, они предотвращают повторное отслеживание, что вы всегда должны учитывать при смешивании чередующихся и вложенных квантификаторов, как я это сделал. Я не думаю, что это было бы проблемой здесь, но я знаю, что если я не упомяну это, кто-то еще скажет. ; -)

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

25 голосов
/ 25 апреля 2009
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);

Источник

17 голосов
/ 18 мая 2012

@ JasonTrue правильно, что удаление HTML-тегов не должно выполняться с помощью регулярных выражений.

Довольно просто удалить теги HTML с помощью HtmlAgilityPack:

public string StripTags(string input) {
    var doc = new HtmlDocument();
    doc.LoadHtml(input ?? "");
    return doc.DocumentNode.InnerText;
}
13 голосов
/ 13 января 2012

Я хотел бы повторить ответ Джейсона, хотя иногда вам нужно наивно разбирать некоторые HTML и извлекать текстовое содержимое.

Мне нужно было сделать это с помощью некоторого HTML, который был создан с помощью текстового редактора, всегда забавного и с играми.

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

В моем случае метки были брошены в этот микс. Кто-то может посчитать мою (очень слегка) менее наивную реализацию полезной отправной точкой.

   /// <summary>
    /// Removes all html tags from string and leaves only plain text
    /// Removes content of <xml></xml> and <style></style> tags as aim to get text content not markup /meta data.
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static string HtmlStrip(this string input)
    {
        input = Regex.Replace(input, "<style>(.|\n)*?</style>",string.Empty);
        input = Regex.Replace(input, @"<xml>(.|\n)*?</xml>", string.Empty); // remove all <xml></xml> tags and anything inbetween.  
        return Regex.Replace(input, @"<(.|\n)*?>", string.Empty); // remove any tags but not there content "<p>bob<span> johnson</span></p>" becomes "bob johnson"
    }
5 голосов
/ 11 июля 2012

попробуйте метод регулярного выражения по этому URL: http://www.dotnetperls.com/remove-html-tags

/// <summary>
/// Remove HTML from string with Regex.
/// </summary>
public static string StripTagsRegex(string source)
{
return Regex.Replace(source, "<.*?>", string.Empty);
}

/// <summary>
/// Compiled regular expression for performance.
/// </summary>
static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);

/// <summary>
/// Remove HTML from string with compiled Regex.
/// </summary>
public static string StripTagsRegexCompiled(string source)
{
return _htmlRegex.Replace(source, string.Empty);
}
3 голосов
/ 13 декабря 2010

используйте это ..

@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
2 голосов
/ 04 сентября 2015

Добавьте .+? в <[^>]*> и попробуйте это регулярное выражение (на основе это ):

<[^>].+?>

c # .net regex demo enter image description here

0 голосов
/ 02 ноября 2016

Используйте этот метод для удаления тегов:

public string From_To(string text, string from, string to)
{
    if (text == null)
        return null;
    string pattern = @"" + from + ".*?" + to;
    Regex rx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
    MatchCollection matches = rx.Matches(text);
    return matches.Count <= 0 ? text : matches.Cast<Match>().Where(match => !string.IsNullOrEmpty(match.Value)).Aggregate(text, (current, match) => current.Replace(match.Value, ""));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...