Вы не указываете это, но я предполагаю, что вы также хотите полностью удалить элементы скрипта и стиля, а не просто удалить тег. Приведенный ниже ответ HTML Agility Pack подходит для удаления тегов, но для удаления скрипта и стиля вам также понадобится что-то вроде stackoverflow.com/questions/13441470/…
Джон
1
В вопросе, обозначенном как дубликат, содержится много информации (и Тони Пони!), Но он запрашивал только открывающие теги, а не все теги. Так что я не уверен, что технически это дубликат. Тем не менее, ответ тот же: не надо.
goodeye
Ответы:
155
Как часто говорилось ранее, вы не должны использовать регулярные выражения для обработки документов XML или HTML. Они не очень хорошо работают с документами HTML и XML, потому что нет способа выразить вложенные структуры в общем виде.
Вы можете использовать следующее.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Это будет работать в большинстве случаев, но будут случаи (например, CDATA, содержащий угловые скобки), когда это не будет работать должным образом.
Это наивная реализация .. То есть <div id = "x <4>">, к сожалению, является допустимым HTML. Хотя справляется с большинством нормальных случаев ..
Райан Эмерл
8
Как уже говорилось, я знаю, что это выражение в некоторых случаях не работает. Я даже не уверен, можно ли без ошибок обработать общий случай любым регулярным выражением.
Даниэль Брюкнер,
1
Нет, это не поможет во всех случаях! его жадный.
Джейк,
13
@Cipher, почему, по-твоему, жадность - это проблема? Если предположить, что совпадение начинается с начала действительного тега HTML, оно никогда не будет выходить за пределы этого тега. Для этого нужен [^>].
Алан Мур,
1
@AlanMoore html не является "обычным языком", т.е. вы не можете правильно сопоставить все, что является допустимым html, с регулярными выражениями. см .: stackoverflow.com/questions/590747/…
Kache
78
Правильный ответ - не делайте этого, используйте HTML Agility Pack .
Отредактировано для добавления:
Чтобы бессовестно украсть комментарий Джесси ниже и избежать обвинений в неадекватном ответе на вопрос по прошествии всего этого времени, вот простой и надежный фрагмент с использованием пакета HTML Agility Pack, который работает даже с самыми несовершенно сформированными, капризными фрагментами 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.
HTML Agility Pack - это не ответ на все вопросы, связанные с работой с HTML (например, что, если вы хотите работать только с фрагментами HTML-кода ?!).
PropellerHead,
7
Он неплохо работает с фрагментами HTML, и это лучший вариант для сценария, описанного исходным плакатом. С другой стороны, Regex работает только с идеализированным HTML и не работает с совершенно правильным HTML, потому что грамматика HTML не является регулярной. Если бы он использовал Ruby, я бы все равно предложил nokogiri, hpricot или beautifulsoup для Python. Лучше всего относиться к HTML как к HTML, а не к произвольному текстовому потоку без грамматики.
JasonTrue
1
HTML не является регулярной грамматикой и поэтому не может быть проанализирован только с помощью регулярных выражений. Вы можете использовать регулярные выражения для лексирования, но не для синтаксического анализа. Это действительно так просто. Лингвисты согласились бы с этим еще до того, как появился HTML.
JasonTrue
20
Это не вопрос мнения. Регулярное выражение может дать вам в основном то, что вы хотите большую часть времени, но в очень распространенных случаях оно не работает. Если вы можете найти лучший / более быстрый парсер, чем HTML Agility Pack, сделайте это, но, пожалуйста, не подвергайте мир еще большему взлому HTML.
JasonTrue
2
Вы не сможете правильно идентифицировать HTML-теги, не проанализировав HTML. Вы понимаете всю грамматику HTML? Посмотрите на злой хак, чтобы подобраться «довольно близко», что предлагают другие ответы, и скажите мне, почему вы хотите поддерживать это. Если вы откажетесь от моего голоса, потому что для вашего образца ввода работает хакерская быстрая попытка, это не сделает ваше решение правильным. Я иногда использовал регулярные выражения для создания отчетов из содержимого HTML или для исправления некоторых ссылок CSS с использованием отрицательного соответствия в & gt; чтобы ограничить вероятность ошибок, но мы сделали дополнительные проверки; это не было универсальной целью.
JasonTrue
38
Вопрос слишком широкий, чтобы на него можно было дать однозначный ответ. Вы говорите об удалении всех тегов из реального HTML-документа, например веб-страницы? Если это так, вам необходимо:
удалите объявление <! DOCTYPE или пролог <? xml, если они существуют
удалить все комментарии SGML
удалить весь элемент HEAD
удалить все элементы SCRIPT и STYLE
делать Грабтар-знает-что с элементами FORM и TABLE
удалите оставшиеся теги
удалите последовательности <! [CDATA [и]]> из разделов CDATA, но оставьте их содержимое в покое
Это просто не в моей голове - я уверен, что это еще не все. После того, как вы все это сделаете, в некоторых местах вы получите слова, предложения и абзацы, соединенные вместе, а в других - большие куски бесполезного пробела.
Но, если вы работаете только с фрагментом и можете просто удалить все теги, вот регулярное выражение, которое я бы использовал:
Сопоставление строк в одинарных и двойных кавычках в их собственных альтернативах достаточно для решения проблемы угловых скобок в значениях атрибутов. Я не вижу необходимости явно сопоставлять имена атрибутов и другие вещи внутри тега, как это делает регулярное выражение в ответе Райана; первая альтернатива обрабатывает все это.
Если вас интересуют эти (?>...)конструкции, они атомные группы . Они делают регулярное выражение немного более эффективным, но, что более важно, предотвращают неконтролируемый откат назад, на что всегда следует обращать внимание, когда вы смешиваете чередование и вложенные квантификаторы, как это сделал я. Я действительно не думаю, что это будет проблемой здесь, но я знаю, что если я не упомяну об этом, это сделает кто-то другой. ;-)
Это регулярное выражение, конечно, не идеально, но оно, вероятно, настолько хорошо, насколько вам когда-либо понадобится.
Это, безусловно, лучший ответ. Вы отвечаете на вопрос автора и объясняете, почему не следует использовать регулярное выражение для данной задачи. Отлично сработано.
JWilliams
26
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
Хотя я немного опоздал с этим, я хотел бы упомянуть, что это также работает с xml, например, созданным Word и другими офисными продуктами. любой, у кого когда-либо была необходимость иметь дело с Word xml, неплохо было бы взглянуть на его использование, потому что он действительно очень помогает, особенно если вам нужно удалить теги из содержимого, а это именно то, для чего мне это нужно.
Стив Петтифер
Когда все остальное казалось безуспешным, этот простой фрагмент кода спас положение. Благодарность!
Тед Крапф,
14
Я хотел бы повторить ответ Джейсона, хотя иногда вам нужно наивно разобрать какой-то 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>publicstaticstringHtmlStrip(thisstring 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"
}
Помимо очевидных кроссплатформенных проблем с переносом строк, неуклюжий квантификатор работает медленно, когда контент разделен. Используйте вещи , как <xml>.*(?!</xml>)</xml>с RegexOptions.SingleLineмодификатором для первых двух и <[^>]*>для последнего. Первые также могут быть объединены путем захваченного чередования имени первого тега и обратных ссылок на него в отрицательном прогнозе и конечном теге.
///<summary>/// Remove HTML from string with Regex.///</summary>publicstaticstringStripTagsRegex(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>publicstaticstringStripTagsRegexCompiled(string source)
{
return _htmlRegex.Replace(source, string.Empty);
}
Ответы:
Как часто говорилось ранее, вы не должны использовать регулярные выражения для обработки документов XML или HTML. Они не очень хорошо работают с документами HTML и XML, потому что нет способа выразить вложенные структуры в общем виде.
Вы можете использовать следующее.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Это будет работать в большинстве случаев, но будут случаи (например, CDATA, содержащий угловые скобки), когда это не будет работать должным образом.
источник
Правильный ответ - не делайте этого, используйте HTML Agility Pack .
Отредактировано для добавления:
Чтобы бессовестно украсть комментарий Джесси ниже и избежать обвинений в неадекватном ответе на вопрос по прошествии всего этого времени, вот простой и надежный фрагмент с использованием пакета HTML Agility Pack, который работает даже с самыми несовершенно сформированными, капризными фрагментами 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.
источник
Вопрос слишком широкий, чтобы на него можно было дать однозначный ответ. Вы говорите об удалении всех тегов из реального HTML-документа, например веб-страницы? Если это так, вам необходимо:
Это просто не в моей голове - я уверен, что это еще не все. После того, как вы все это сделаете, в некоторых местах вы получите слова, предложения и абзацы, соединенные вместе, а в других - большие куски бесполезного пробела.
Но, если вы работаете только с фрагментом и можете просто удалить все теги, вот регулярное выражение, которое я бы использовал:
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
Сопоставление строк в одинарных и двойных кавычках в их собственных альтернативах достаточно для решения проблемы угловых скобок в значениях атрибутов. Я не вижу необходимости явно сопоставлять имена атрибутов и другие вещи внутри тега, как это делает регулярное выражение в ответе Райана; первая альтернатива обрабатывает все это.
Если вас интересуют эти
(?>...)
конструкции, они атомные группы . Они делают регулярное выражение немного более эффективным, но, что более важно, предотвращают неконтролируемый откат назад, на что всегда следует обращать внимание, когда вы смешиваете чередование и вложенные квантификаторы, как это сделал я. Я действительно не думаю, что это будет проблемой здесь, но я знаю, что если я не упомяну об этом, это сделает кто-то другой. ;-)Это регулярное выражение, конечно, не идеально, но оно, вероятно, настолько хорошо, насколько вам когда-либо понадобится.
источник
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
Источник
источник
@JasonTrue правильно, что удаление тегов HTML не должно выполняться с помощью регулярных выражений.
Убрать HTML-теги с помощью HtmlAgilityPack довольно просто:
public string StripTags(string input) { var doc = new HtmlDocument(); doc.LoadHtml(input ?? ""); return doc.DocumentNode.InnerText; }
источник
Я хотел бы повторить ответ Джейсона, хотя иногда вам нужно наивно разобрать какой-то 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" }
источник
<xml>.*(?!</xml>)</xml>
сRegexOptions.SingleLine
модификатором для первых двух и<[^>]*>
для последнего. Первые также могут быть объединены путем захваченного чередования имени первого тега и обратных ссылок на него в отрицательном прогнозе и конечном теге.попробуйте метод регулярного выражения по этому 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); }
источник
использовать это..
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
источник
Добавить
.+?
в<[^>]*>
и попробовать это регулярное выражение (основание на это ):Демо c # .net regex
источник
Используйте этот метод для удаления тегов:
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, "")); }
источник