Як використовувати регулярний вираз C # для заміни / видалення всіх тегів HTML, включаючи кутові дужки? Може хтось, будь ласка, допоможе мені з кодом?
Як використовувати регулярний вираз C # для заміни / видалення всіх тегів HTML, включаючи кутові дужки? Може хтось, будь ласка, допоможе мені з кодом?
Відповіді:
Як часто говорилося раніше, не слід використовувати регулярні вирази для обробки XML або HTML документів. Вони не дуже добре працюють з документами HTML і XML, тому що немає можливості виразити вкладені структури загальним способом.
Ви можете використовувати наступне.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Це буде працювати в більшості випадків, але будуть випадки (наприклад, CDATA, що містять кутові дужки), коли це не буде працювати, як очікувалося.
Правильна відповідь - не робіть цього, використовуйте пакет пакету спритності HTML .
Відредаговано, щоб додати:
Щоб безсоромно вкрастись від коментаря, поданого нижче від jesse, і уникнути звинувачення у неадекватній відповіді на питання після закінчення цього часу, ось простий надійний фрагмент із використанням пакету HTML Agility, який працює навіть з найбільш недосконало сформованими, примхливими бітами 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 може надати вам надійне рішення, яке зменшить потребу вручну виправити відхилення, які можуть бути наслідком наївного поводження з 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);
}
Додати .+?
в <[^>]*>
і спробувати це регулярний вираз (підстава на це ):
<[^>].+?>
Використовуйте цей метод для видалення тегів:
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, ""));
}