Nie wskazujesz tego, ale wnioskuję, że chcesz również całkowicie usunąć skrypty i elementy stylu, a nie tylko usunąć tag. Poniższa odpowiedź HTML Agility Pack jest poprawna do usuwania tagów, ale aby usunąć skrypt i styl, potrzebujesz również czegoś takiego jak stackoverflow.com/questions/13441470/ ...
Jan
1
Pytanie wskazane jako duplikat zawiera wiele informacji (i Tony the Pony!), Ale dotyczyło tylko otwierania tagów, a nie wszystkich tagów. Więc nie jestem pewien, czy technicznie jest to duplikat. To powiedziawszy, odpowiedź jest taka sama: nie.
goodeye
Odpowiedzi:
154
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.
To naiwna implementacja. Oznacza to, że <div id = "x <4>"> jest niestety prawidłowym kodem HTML. Zajmuje się jednak większością rozsądnych spraw ...
Ryan Emerle
8
Jak już wspomniano, zdaję sobie sprawę, że to wyrażenie w niektórych przypadkach zawiedzie. Nie jestem nawet pewien, czy w ogólnym przypadku można obsłużyć dowolne wyrażenie regularne bez błędów.
Daniel Brückner
1
Nie, to zawiedzie we wszystkich przypadkach! jest chciwy.
Jake
13
@Cipher, dlaczego uważasz, że chciwość jest problemem? Zakładając, że dopasowanie zaczyna się na początku prawidłowego tagu HTML, nigdy nie wyjdzie poza koniec tego tagu. Do tego służy [^>].
Alan Moore
1
@AlanMoore html nie jest „zwykłym językiem”, tj. Nie można poprawnie dopasować wszystkiego, co jest poprawnym html do wyrażeń regularnych. patrz: stackoverflow.com/questions/590747/…
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 =newHtmlDocument();
doc.LoadHtml(Properties.Resources.HtmlContents);var text = doc.DocumentNode.SelectNodes("//body//text()").Select(node => node.InnerText);StringBuilder output =newStringBuilder();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.
HTML Agility Pack nie jest odpowiedzią na wszystko, co dotyczy pracy z HTML (np. Co jeśli chcesz pracować tylko z fragmentami kodu HTML ?!).
PropellerHead
7
Działa całkiem dobrze z fragmentami HTML i jest to najlepsza opcja dla scenariusza opisanego przez oryginalny plakat. Z drugiej strony Regex działa tylko z wyidealizowanym kodem HTML i zepsuje się z całkowicie poprawnym HTML, ponieważ gramatyka HTML nie jest regularna. Gdyby używał Rubiego, nadal zasugerowałbym nokogiri, hpricot lub beautifulsoup dla Pythona. Najlepiej traktować HTML jak HTML, a nie jakiś dowolny strumień tekstowy bez gramatyki.
JasonTrue
1
HTML nie jest zwykłą gramatyką i dlatego nie może być analizowany wyłącznie za pomocą wyrażeń regularnych. Możesz używać wyrażeń regularnych do leksowania, ale nie do analizowania. To naprawdę takie proste. Lingwiści zgodziliby się na to, zanim jeszcze istniał HTML.
JasonTrue
20
To nie jest kwestia opinii. Wyrażenie regularne może w większości przypadków zapewniać Ci 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.
JasonTrue
2
Nie można poprawnie zidentyfikować znaczników HTML bez analizy kodu HTML. Czy rozumiesz całą gramatykę dotyczącą HTML? Zobacz złowrogi hack, aby zbliżyć się „całkiem blisko”, jak sugerują inne odpowiedzi, i powiedz mi, dlaczego chcesz to utrzymać. Odebranie mi głosu, ponieważ niefortunna, szybka próba zadziała na przykładowe dane wejściowe, nie spowoduje, że Twoje rozwiązanie będzie poprawne. Czasami używałem wyrażeń regularnych do generowania raportów z zawartości HTML lub do poprawiania niektórych odniesień CSS za pomocą dopasowania wykluczającego w & gt; aby ograniczyć ryzyko błędów, ale przeprowadziliśmy dodatkowe weryfikacje; to nie był cel ogólny.
JasonTrue
38
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:
usuń deklarację <! DOCTYPE lub <? xml prolog, jeśli istnieją
usuń wszystkie komentarze SGML
usuń cały element HEAD
usuń wszystkie elementy SCRIPT i STYLE
zrobić Grabthar-wie-co z elementami FORM i TABLE
usuń pozostałe tagi
usuń sekwencje <! [CDATA [i]]> z sekcji CDATA, ale pozostaw ich zawartość w spokoju
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:
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ć.
To zdecydowanie najlepsza odpowiedź. Odpowiadasz na pytanie nadawcy i wyjaśniasz, dlaczego w zadaniu nie należy używać wyrażenia regularnego. Dobra robota.
Chociaż jestem trochę spóźniony, chciałbym wspomnieć, że działa to również w przypadku XML, takiego jak ten produkowany przez Word i inne produkty biurowe. każdy, kto kiedykolwiek miał potrzebę radzenia sobie z Word xml, zrobiłby dobrze, gdyby spojrzał na użycie tego, ponieważ bardzo pomaga, zwłaszcza jeśli chcesz usunąć tagi z treści, co jest dokładnie tym, do czego go potrzebowałem.
Steve Pettifer
Kiedy wszystko inne wydawało się zawodzić, ten prosty fragment kodu uratował sytuację. Dzięki!
Ted Krapf
14
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>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. returnRegex.Replace(input,@"<(.|\n)*?>",string.Empty);// remove any tags but not there content "<p>bob<span> johnson</span></p>" becomes "bob johnson"}
Oprócz oczywistych problemów z łamaniem linii między platformami, posiadanie niezadowolonego kwantyfikatora jest powolne, gdy zawartość jest rozdzielana. Używaj rzeczy, jak <xml>.*(?!</xml>)</xml>z RegexOptions.SingleLinemodyfikatora 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.
/// <summary>/// Remove HTML from string with Regex./// </summary>publicstaticstringStripTagsRegex(string source){returnRegex.Replace(source,"<.*?>",string.Empty);}/// <summary>/// Compiled regular expression for performance./// </summary>staticRegex _htmlRegex =newRegex("<.*?>",RegexOptions.Compiled);/// <summary>/// Remove HTML from string with compiled Regex./// </summary>publicstaticstringStripTagsRegexCompiled(string source){return _htmlRegex.Replace(source,string.Empty);}
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.
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.
źródło
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:
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.
źródło
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:
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ć.
źródło
Źródło
źródło
@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:
źródło
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.
źródło
<xml>.*(?!</xml>)</xml>
zRegexOptions.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
źródło
Użyj tego..
źródło
Dodaj
.+?
do<[^>]*>
wypróbowania tego regex (baza na to ):c # .net regex demo
źródło
Użyj tej metody, aby usunąć tagi:
źródło