Jak używać wyrażenia regularnego C # do zastępowania / usuwania wszystkich tagów HTML, w tym nawiasów kątowych? Czy ktoś może mi pomóc z kodem?
Jak używać wyrażenia regularnego C # do zastępowania / usuwania wszystkich tagów HTML, w tym nawiasów kątowych? Czy ktoś może mi pomóc z kodem?
Odpowiedzi:
Jak często wspomniano wcześniej, nie należy używać wyrażeń regularnych do przetwarzania dokumentów XML lub HTML. Nie radzą sobie zbyt dobrze z dokumentami HTML i XML, ponieważ nie ma sposobu na ogólne wyrażenie zagnieżdżonych struktur.
Możesz użyć następującego.
String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);
Będzie to działać w większości przypadków, ale w niektórych przypadkach (na przykład CDATA zawierający nawiasy ostre) nie będzie to działać zgodnie z oczekiwaniami.
Prawidłowa odpowiedź brzmi: nie rób tego, użyj pakietu HTML Agility Pack .
Edytowano, aby dodać:
Aby bezwstydnie okraść poniższy komentarz jesse i nie zostać oskarżonym o niewystarczającą odpowiedź na pytanie po tak długim czasie, oto prosty, niezawodny fragment kodu wykorzystujący pakiet HTML Agility Pack, który działa nawet z najbardziej niedoskonałymi, kapryśnymi fragmentami 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());
Istnieje bardzo niewiele możliwych do obronienia przypadków użycia wyrażenia regularnego do analizowania kodu HTML, ponieważ HTML nie może być poprawnie przeanalizowany bez świadomości kontekstowej, której zapewnienie jest bardzo bolesne nawet w nietradycyjnym silniku regex. Możesz dostać się tam częściowo za pomocą wyrażenia regularnego, ale musisz przeprowadzić ręczną weryfikację.
Html Agility Pack może zapewnić solidne rozwiązanie, które zmniejszy potrzebę ręcznego naprawiania aberracji, które mogą wynikać z naiwnego traktowania HTML jako gramatyki bezkontekstowej.
Wyrażenie regularne może w większości przypadków zapewniać to, czego potrzebujesz, ale w bardzo typowych przypadkach zawodzi. Jeśli możesz znaleźć lepszy / szybszy parser niż HTML Agility Pack, zrób to, ale nie narażaj świata na więcej zepsutego hakera HTML.
Pytanie jest zbyt szerokie, aby można było na nie odpowiedzieć ostatecznie. Czy mówisz o usunięciu wszystkich tagów z rzeczywistego dokumentu HTML, takiego jak strona internetowa? Jeśli tak, musisz:
To tylko z głowy - jestem pewien, że jest więcej. Gdy już to zrobisz, w niektórych miejscach słowa, zdania i akapity będą biegły razem, aw innych duże fragmenty bezużytecznych spacji.
Ale zakładając, że pracujesz tylko z fragmentem i możesz uciec po prostu usuwając wszystkie tagi, oto wyrażenie regularne, którego użyłbym:
@"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>"
Dopasowanie ciągów w pojedynczych i podwójnych cudzysłowach w ich własnych alternatywach wystarczy, aby rozwiązać problem nawiasów ostrych w wartościach atrybutów. Nie widzę potrzeby jawnego dopasowywania nazw atrybutów i innych rzeczy w tagu, jak robi to wyrażenie regularne w odpowiedzi Ryana; pierwsza alternatywa obsługuje to wszystko.
Jeśli zastanawiasz się nad tymi (?>...)
konstrukcjami, są to grupy atomowe . Sprawiają, że wyrażenia regularne są trochę bardziej wydajne, ale co ważniejsze, zapobiegają niekontrolowanemu cofaniu się, na co zawsze należy uważać, gdy mieszasz przemienność i zagnieżdżone kwantyfikatory, tak jak to zrobiłem. Naprawdę nie sądzę, żeby to był problem, ale wiem, że jeśli o tym nie wspomnę, zrobi to ktoś inny. ;-)
To wyrażenie regularne nie jest oczywiście idealne, ale prawdopodobnie jest tak dobre, jak kiedykolwiek będziesz potrzebować.
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);
@JasonTrue ma rację, że usuwanie znaczników HTML nie powinno odbywać się za pomocą wyrażeń regularnych.
Usunięcie tagów HTML za pomocą HtmlAgilityPack jest dość proste:
public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}
Chciałbym powtórzyć odpowiedź Jasona, chociaż czasami trzeba naiwnie przeanalizować jakiś kod HTML i wyciągnąć zawartość tekstową.
Musiałem to zrobić za pomocą jakiegoś HTML, który został stworzony przez edytor tekstu sformatowanego, zawsze zabawny i gry.
W takim przypadku może być konieczne usunięcie zawartości niektórych tagów, a także samych tagów.
W moim przypadku i tagi zostały wrzucone do tej mieszanki. Ktoś może uznać moją (nieco) mniej naiwną implementację za przydatny punkt wyjścia.
/// <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>
z RegexOptions.SingleLine
modyfikatora przez pierwsze dwa i <[^>]*>
na ostatnim. Pierwsze z nich można również łączyć poprzez przechwyconą przemianę w nazwie pierwszego znacznika i odwołania wsteczne do niego w negatywnym tagu wyprzedzającym i końcowym.
wypróbuj metodę wyrażeń regularnych pod tym adresem 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);
}
Użyj tej metody, aby usunąć tagi:
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, ""));
}