Nie można parsować [X] HTML za pomocą wyrażenia regularnego. Ponieważ HTML nie może zostać przeanalizowany przez wyrażenie regularne. Regex nie jest narzędziem, którego można użyć do prawidłowego parsowania HTML. Jak już wiele razy odpowiadałem na pytania HTML i regex, użycie regex nie pozwoli ci na używanie HTML. Wyrażenia regularne to narzędzie, które nie jest wystarczająco zaawansowane, aby zrozumieć konstrukcje stosowane przez HTML. HTML nie jest językiem regularnym i dlatego nie można go analizować za pomocą wyrażeń regularnych. Kwerendy Regex nie są przystosowane do podziału HTML na znaczące części. tyle razy, ale do mnie to nie dociera. Nawet ulepszone nieregularne wyrażenia regularne używane przez Perla nie są w stanie analizować HTML. Nigdy mnie nie zmusisz. HTML jest językiem o wystarczającej złożoności, którego nie można przeanalizować za pomocą wyrażeń regularnych. Nawet Jon Skeet nie może parsować HTML za pomocą wyrażeń regularnych. Za każdym razem, gdy próbujesz parsować HTML za pomocą wyrażeń regularnych, bezbożne dziecko płacze krwią dziewic, a rosyjscy hakerzy wtłaczają twoją aplikację internetową. Analizowanie HTML za pomocą wyrażeń regularnych przywołuje skażone dusze do świata żywych. HTML i regex idą w parze jak miłość, małżeństwo i rytualne dzieciobójstwo. <center> nie może go utrzymać, jest za późno. Siła wyrażeń regularnych i HTML razem w tej samej przestrzeni koncepcyjnej zniszczy twój umysł jak bardzo wodnisty kit. Jeśli parsujesz HTML z wyrażeniami regularnymi, poddajesz się im i ich bluźnierczym sposobom, które skazują nas wszystkich na nieludzką trud dla Tego, którego imienia nie można wyrazić w Podstawowej Wielojęzycznej Planie, on przychodzi. HTML-plus-regexp zlikwiduje cnoty czujących podczas obserwowania, a twoja psychika usycha w ataku horroru.jest za późno, jest za późno, nie możemy ocalić transekcji dziecka, ponieważ regex pochłonie całą żywą tkankę (z wyjątkiem HTML, którego nie może, jak wcześniej przepowiedziano) drogi panie, pomóż nam, jak ktokolwiek może przetrwać tę plagę używając wyrażeń regularnych do analizy HTML skazał ludzkość na wieczność przerażających tortur i dziur w zabezpieczeniach, używając rege x jako narzędzia do przetwarzania HTML ustanawia przerwę między tym światem a przerażającym królestwem ͒ͪo͛ͫrrupt bytów (takich jak byty SGML, ale bardziej skorumpowane) zaledwie rzut oka na świat reg ex parserami dla HTML będzie ins tantly transportowej ap świadomość rogrammer za I nto aw orl d nieustanny krzyk, przychodziThe epidemiczny sl ithy regex zakażenie wil l pożerać swoim HT ML parsera, stosowanie i egzystencji wszystkim czasu jak Visual Basic tylko gorzej przychodzi on com es nie fi GHT h e przychodzi, hi s Unholy Radiance de stro҉ying wszystko oświecenia, HTML tagi przecieka fr̶ǫm yo ur oczy jak liq uid p Ain, piosenka regularnych exp re ssion parsowania będzie Gaśnice anguish głosy mor tal człowieka z sp tu widzę, to może zobaczyć to jest piękne t on f inal snuf
fing o f kłamstwo s Man wszystko stracone A ll SLOST p e pony przyjdzie s on Com es Współtworzył ME s t się Ich lub permeat es al l MÓJ Fac god E MY FACE ᵒh n O NO noo O na Θ zatrzymania t on z * ̶͑̾̾ Gl eS ͎a̧͈͖r̽̾̈́͒͑e
n ot rè̑ͧ̌aͨl̘̝̙̃ͤ͂̾̆ ZA̡͊͠͝LGΌ ISͮ̂҉̯͈͕̹̘̱ T O͇̹̺ͅƝ̴ȳ̳ TH̘ ͖͖͖̉ ͠P̯͍̭O̚ N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝ S̨̥̫͎̭ͯ̿̔̀ͅ
Czy zamiast tego próbowałeś użyć parsera XML?
Uwaga moderatora
Ten post jest zablokowany, aby zapobiec niewłaściwym edycjom jego treści. Post wygląda dokładnie tak, jak powinien - nie ma problemów z jego treścią. Proszę nie oznaczać tego dla naszej uwagi.
Chociaż arbitralny HTML z tylko wyrażeniem regularnym jest niemożliwy, czasem należy go użyć do parsowania ograniczonego, znanego zestawu HTML.
Jeśli masz mały zestaw stron HTML, z których chcesz zeskrobać dane, a następnie wrzucić je do bazy danych, wyrażenia regularne mogą działać poprawnie. Na przykład ostatnio chciałem uzyskać nazwiska, partie i dystrykty australijskich przedstawicieli federalnych, które dostałem ze strony internetowej Parlamentu. To była ograniczona, jednorazowa praca.
Regexy działały dla mnie dobrze i były bardzo szybkie w konfiguracji.
źródło
&foo;
kodowanie iCDATA
sekcje? Używasz minimalizatora HTML, aby usunąć wszystkie białe znaki w dokumencie, których przeglądarka nie wyświetla? Parser XML nie będzie się tym przejmował, podobnie jak dobrze napisana instrukcja XPath. Z drugiej strony „parser” oparty na wyrażeniach regularnych ...<font>
itd .: brak klas lub identyfikatorów ułatwiających poruszanie się po DOM. Po całym dniu walki z „właściwym” podejściem, w końcu przerzuciłem się na rozwiązanie regex i uruchomiłem je w ciągu godziny.Myślę, że wadą jest to, że HTML to gramatyka Chomsky'ego typu 2 (gramatyka bez kontekstu), a RegEx to gramatyka Chomsky'ego typu 3 (gramatyka zwykła) . Ponieważ gramatyka typu 2 jest zasadniczo bardziej złożona niż gramatyka typu 3 (patrz hierarchia Chomsky'ego ), matematycznie niemożliwe jest parsowanie XML za pomocą RegEx.
Ale wielu będzie próbowało, niektórzy nawet twierdzą, że odnieśli sukces - ale dopóki inni nie odkryją winy i całkowicie nie zepsują cię.
źródło
A -> s A e
). (X) HTML nie ma tej właściwości w znaczniku początkowym: znacznik początkowy nie może zawierać innych znaczników początkowych. Podzbiór, który OP próbuje analizować, nie jest CFG.Nie słuchaj tych facetów. Jesteś całkowicie można analizować gramatyk bezkontekstowych z regex jeśli złamiesz zadanie na mniejsze kawałki. Możesz wygenerować prawidłowy wzorzec za pomocą skryptu, który wykonuje każdy z nich w kolejności:
Sam jeszcze nie skończyłem ostatniej części, ale wiem, że się zbliżam. Ciągle rzuca
CthulhuRlyehWgahnaglFhtagnException
s z jakiegoś powodu, więc zamierzam przenieść go na VB 6 i użyćOn Error Resume Next
. Zaktualizuję kod, gdy zbadam te dziwne drzwi, które właśnie otworzyły się w ścianie. HmmPS Pierre de Fermat również wymyślił, jak to zrobić, ale margines, w którym pisał, nie był wystarczająco duży dla kodu.
źródło
Oświadczenie : użyj parsera, jeśli masz taką opcję. To mówi...
Oto wyrażenie, którego używam (!) Do dopasowania tagów HTML:
To może nie być idealne, ale uruchomiłem ten kod przez wiele HTML. Pamiętaj, że wyłapuje nawet dziwne rzeczy
<a name="badgenerator"">
, które pojawiają się w Internecie.Sądzę, że żeby nie pasowało do niezależnych tagów, możesz użyć negatywnego spojrzenia Kobi :
lub po prostu połącz, jeśli nie, a jeśli nie.
Do downvoters: To działa kod z rzeczywistego produktu. Wątpię, aby ktokolwiek czytający tę stronę miał wrażenie, że użycie wyrażeń regularnych w HTML jest społecznie akceptowalne.
Zastrzeżenie : Należy zauważyć, że ten regex nadal rozkłada się w obecności blokach CDATA, komentarze i elementów skryptów i stylów. Dobra wiadomość jest taka, że możesz się pozbyć osób używających wyrażenia regularnego ...
źródło
<!doctype html><title><</title>
. Proste'<!doctype html><title><</title>'.match(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g)
zwroty["<!doctype html>", "<title>", "<</title>"]
powinny["<title>", "</title>"]
.Są ludzie, którzy powiedzą ci, że Ziemia jest okrągła (a może Ziemia jest spłaszczoną sferoidą, jeśli chcą użyć dziwnych słów). Oni kłamią.
Są ludzie, którzy powiedzą ci, że Wyrażenia regularne nie powinny być rekurencyjne. Ograniczają cię. Muszą cię ujarzmić i robią to, utrzymując cię w ignorancji.
Możesz żyć w ich rzeczywistości lub wziąć czerwoną pigułkę.
Podobnie jak lord marszałek (czy jest krewnym klasy marszałka .NET?), Widziałem Regex-Verse oparty na
stosach odwrotnychi wróciłem z wiedzą omocach, której nie możesz sobie wyobrazić. Tak, myślę, że chronił ich Stary lub Dwa, ale oglądali piłkę nożną w telewizji, więc nie było to trudne.Myślę, że przypadek XML jest dość prosty. RegEx (w składni .NET), deflowany i kodowany w base64, aby ułatwić zrozumienie słabemu umysłowi, powinien wyglądać mniej więcej tak:
Dostępne opcje to
RegexOptions.ExplicitCapture
. Grupa przechwytywania, której szukaszELEMENTNAME
. Jeśli grupa przechwytywaniaERROR
nie jest pusta, wystąpił błąd analizy i regex został zatrzymany.Jeśli masz problemy z przekonwertowaniem go na regex czytelny dla człowieka, powinno to pomóc:
Jeśli nie jesteś pewien, nie, NIE żartuję (ale może kłamię). To będzie działać. Zbudowałem mnóstwo testów jednostkowych, aby to przetestować, a nawet użyłem (części) testów zgodności . Jest to tokenizer, a nie pełnoprawny parser, więc podzieli XML tylko na tokeny składowe. Nie będzie analizować / integrować DTD.
Och ... jeśli chcesz kod źródłowy wyrażenia regularnego, z kilkoma metodami pomocniczymi:
regex, aby tokenizować xml lub pełny zwykły regex
źródło
W powłoce możesz analizować HTML używając sed :
Powiązane (dlaczego nie powinieneś używać dopasowania wyrażenia regularnego):
źródło
Zgadzam się, że właściwe narzędzie do analizy XML, a zwłaszcza HTML to analizator składni, a nie silnik wyrażeń regularnych. Jednak, jak zauważyli inni, czasem użycie wyrażenia regularnego jest szybsze, łatwiejsze i wykonuje zadanie, jeśli znasz format danych.
Microsoft faktycznie ma sekcję Najlepszych praktyk dotyczących wyrażeń regularnych w .NET Framework, a konkretnie mówi o rozważaniu źródła wejściowego .
Wyrażenia regularne mają ograniczenia, ale czy bierzesz pod uwagę następujące kwestie?
.NET Framework jest wyjątkowy, jeśli chodzi o wyrażenia regularne, ponieważ obsługuje definicje grup równoważących .
Z tego powodu uważam, że MOŻESZ parsować XML przy użyciu wyrażeń regularnych. Zauważ jednak, że musi to być poprawny XML ( przeglądarki bardzo wybaczają HTML i pozwalają na złą składnię XML wewnątrz HTML ). Jest to możliwe, ponieważ „definicja grupy równoważącej” pozwoli silnikowi wyrażeń regularnych działać jako PDA.
Cytat z artykułu 1 cytowanego powyżej:
Rozważ następujące wyrażenie regularne:
Użyj flag:
Wyjaśnienie wyrażeń regularnych (wbudowane)
Możesz tego spróbować w A Better .NET Regular Expression Tester .
Użyłem przykładowego źródła:
Znaleziono dopasowanie:
chociaż tak naprawdę wyszło tak:
Wreszcie, naprawdę podobał mi się artykuł Jeffa Atwooda: Parsing Html The Cthulhu Way . Zabawne, że przytacza odpowiedź na to pytanie, które obecnie ma ponad 4 tys. Głosów.
źródło
System.Text
nie jest częścią C #. Jest częścią .NET.(?=<ul\s*id="matchMe"\s*type="square"\s*>) # match start with <ul id="matchMe"...
), pomiędzy „<ul” i „id” powinno być\s+
, nie\s*
, chyba że chcesz, żeby pasowało <ulid = ...;)\s+
zamiast\s*
.<img src="images/pic.jpg" />
/
gdzieś w środku błąd<img src="images/pic.jpg" />
HTML.Sugeruję użycie QueryPath do analizowania XML i HTML w PHP. Jest to zasadniczo taka sama składnia jak jQuery, tylko po stronie serwera.
źródło
Chociaż odpowiedzi, których nie można parsować HTML za pomocą wyrażeń regularnych, są poprawne, nie mają tutaj zastosowania. OP chce tylko parsować jeden znacznik HTML z wyrażeniami regularnymi, i można to zrobić za pomocą wyrażenia regularnego.
Sugerowana regex jest nieprawidłowa:
Jeśli dodać coś do regex, przez backtracking może być zmuszony dopasować głupie rzeczy, jak
<a >>
,[^/]
jest zbyt liberalne. Zauważ też, że<space>*[^/]*
jest zbędny, ponieważ[^/]*
może również pasować do spacji.Moja sugestia byłaby
Gdzie
(?<! ... )
jest (w Perl regexes) negatywne spojrzenie wstecz. Odczytuje „a <, następnie słowo, a następnie cokolwiek, co nie jest a, z których ostatnim może nie być /, a następnie>”.Zauważ, że pozwala to na takie rzeczy
<a/ >
(jak oryginalne wyrażenie regularne), więc jeśli chcesz czegoś bardziej restrykcyjnego, musisz zbudować wyrażenie regularne w celu dopasowania par atrybutów oddzielonych spacjami.źródło
>
znak. Zgadzam się, co sugeruje OP można zrobić za pomocą wyrażenia regularnego, ale ten przedstawiony tutaj jest zbyt uproszczony.Próbować:
Jest podobny do twojego, ale ostatni
>
nie może być po cięciu, a także akceptujeh1
.źródło
>
symbol właściwie uciekł do & gt ;.>
jest poprawny w wartości atrybutu. Rzeczywiście, w serializacji „kanoniczny XML” nie można używać>
. (Co nie jest do końca istotne, z wyjątkiem podkreślenia, że>
wartość atrybutu wcale nie jest niczym niezwykłym).<div title="this tag is a <div></div>">hello</div>
Sun Tzu, starożytny chiński strateg, generał i filozof, powiedział:
W tym przypadku twoim wrogiem jest HTML i jesteś albo sobą, albo wyrażeniem regularnym. Możesz nawet być Perlem z nieregularnym wyrażeniem regularnym. Zna HTML. Znać siebie.
Skomponowałem haiku opisujące naturę HTML.
Skomponowałem także haiku opisujące naturę wyrażenia regularnego w Perlu.
źródło
Wynik:
Zasadniczo wystarczy zdefiniować nazwy węzłów elementów, które są samozamykające się, załadować cały ciąg HTML do biblioteki DOM, pobrać wszystkie elementy, przejrzeć i odfiltrować te, które nie są samozamykające się i działać na nich.
Jestem pewien, że już wiesz, że nie powinieneś używać wyrażenia regularnego w tym celu.
źródło
NS
i określ przestrzeń nazw.Nie wiem dokładnie, jak tego potrzebujesz, ale jeśli używasz również platformy .NET, czy nie możesz użyć pakietu HTML Agility Pack ?
Fragment:
źródło
Chcesz, aby pierwsza
>
nie była poprzedzona znakiem/
. Sprawdź tutaj, jak to zrobić. Jest to określane jako negatywne spojrzenie.Jednak naiwna implementacja tego skończy się dopasowaniem
<bar/></foo>
w tym przykładowym dokumencieCzy możesz podać trochę więcej informacji na temat problemu, który próbujesz rozwiązać? Czy programowo iterujesz po tagach?
źródło
W3C wyjaśnia parsowanie w formie pseudo wyrażenia regularnego:
W3C Link
Poniższe linki VaR
QName
,S
orazAttribute
aby uzyskać jaśniejszy obraz.Na tej podstawie możesz utworzyć całkiem dobre wyrażenie regularne do obsługi takich rzeczy, jak usuwanie tagów.
źródło
Jeśli potrzebujesz tego dla PHP:
W PHP DOM funkcje nie będą działać prawidłowo, jeśli nie jest prawidłowo sformatowany XML. Bez względu na to, o ile lepsze jest ich wykorzystanie dla reszty ludzkości.
simplehtmldom jest dobry, ale uważam, że jest trochę wadliwy, i jest dość obciążony pamięcią [Zawiesza się na dużych stronach.]
Nigdy nie korzystałem z zapytania , więc nie mogę komentować jego przydatności.
Kolejnym do wypróbowania jest mój DOMParser, który jest bardzo lekki w zakresie zasobów i od dłuższego czasu korzystam z niego szczęśliwie. Prosty do nauczenia i potężny.
W przypadku Python i Java opublikowano podobne linki.
Dla downvoterów - napisałem swoją klasę tylko wtedy, gdy parsery XML okazały się niezdolne do wytrzymania rzeczywistego użycia. Religijne wycofywanie głosów po prostu uniemożliwia opublikowanie użytecznych odpowiedzi - proszę, trzymaj sprawy w perspektywie pytania.
źródło
Oto rozwiązanie:
Aby go głęboko przetestować, wprowadziłem tagi automatycznego zamykania łańcucha, takie jak:
Wprowadziłem również tagi z:
Jeśli znajdziesz coś, co nie działa w powyższym dowodzie koncepcji, jestem dostępny w analizie kodu, aby poprawić swoje umiejętności.
<EDIT> Zapomniałem, że pytaniem użytkownika było uniknięcie parsowania tagów samozamykających się. W tym przypadku wzór jest prostszy, zmieniając się w to:
Użytkownik @ridgerunner zauważył, że wzorzec nie dopuszcza atrybutów bez cudzysłowu lub atrybutów bez wartości . W takim przypadku dokładne dostrojenie przynosi nam następujący wzór:
</EDIT>
Zrozumienie wzoru
Jeśli ktoś jest zainteresowany uzyskaniem dodatkowych informacji na temat tego wzoru, podaję następujące zdanie:
Mała wskazówka: aby lepiej przeanalizować ten kod, konieczne jest sprawdzenie wygenerowanego kodu źródłowego, ponieważ nie podałem żadnych znaków specjalnych HTML.
źródło
<option selected>
. Nie pasuje również do prawidłowych tagów z niecytowanymi wartościami atrybutów, tj<p id=10>
.< a href="http://wtf.org" >
Jestem prawie pewien, że jest to zgodne z prawem, ale nie pasujesz.Ilekroć muszę szybko wyodrębnić coś z dokumentu HTML, używam Tidy do konwersji na XML, a następnie używam XPath lub XSLT, aby uzyskać to, czego potrzebuję. W twoim przypadku coś takiego:
źródło
Wcześniej korzystałem z narzędzia open source o nazwie HTMLParser . Jest zaprojektowany do parsowania HTML na różne sposoby i całkiem dobrze służy temu celowi. Może parsować HTML jako różne treenode i możesz łatwo użyć jego interfejsu API, aby uzyskać atrybuty z węzła. Sprawdź to i sprawdź, czy to może ci pomóc.
źródło
Lubię parsować HTML z wyrażeniami regularnymi. Nie próbuję parsować idiotycznego kodu HTML, który został celowo uszkodzony. Ten kod jest moim głównym parserem (edycja Perla):
Nazywa się htmlsplit, dzieli HTML na linie, z jednym znacznikiem lub kawałkiem tekstu w każdej linii. Linie mogą być następnie przetwarzane za pomocą innych narzędzi tekstowych i skryptów, takich jak grep , sed , Perl itp. Nawet nie żartuję :) Ciesz się.
Jeśli chcesz przetwarzać ogromne strony internetowe, łatwo jest przenieść mój skrypt Perla slurp-all-first-Perl do fajnego streamingu. Ale to nie jest naprawdę konieczne.
Założę się, że zostanę za to zlekceważony.
Podział HTML
Wbrew moim oczekiwaniom zyskało to aprobatę, dlatego zaproponuję lepsze wyrażenia regularne:
Są dobre dla XML / XHTML.
Z niewielkimi zmianami może poradzić sobie z niechlujnym HTML ... lub najpierw przekonwertować HTML -> XHTML.
Najlepszym sposobem pisania wyrażeń regularnych jest styl Lex / Yacc , a nie jako nieprzejrzyste jednowierszowe lub komentowane wieloliniowe potworności. Jeszcze tego nie zrobiłem; ci ledwie go potrzebują.
źródło
/(\w+)="(.*?)"/
zakłada podwójne cudzysłowy. Pominie wartości w pojedynczych cudzysłowach. W wersji HTML 4 i wcześniejszych dozwolona jest niecytowana wartość, jeśli jest to proste słowo./(\w+)="(.*?)"/
może fałszywie pasować do tekstu, który wygląda jak atrybut w atrybucie, np<img title="Nope down='up' for aussies" src="..." />
. Jeśli zostanie zastosowany globalnie, będzie pasować do takich rzeczy w zwykłym tekście lub w komentarzach HTML.Oto parser oparty na PHP, który analizuje HTML przy użyciu jakiegoś bezbożnego wyrażenia regularnego. Jako autor tego projektu mogę powiedzieć, że można analizować HTML za pomocą wyrażeń regularnych, ale nie jest to wydajne. Jeśli potrzebujesz rozwiązania po stronie serwera (tak jak ja dla mojej wtyczki WordPress typu WP-Typography ), to działa.
źródło
Istnieje kilka przyjemnych Wyrażenia regularne do zastąpienia HTML z BBCode tutaj . Wszyscy, którzy mówili, zauważcie, że nie próbuje on w pełni parsować HTML-a, tylko go odkażać. Prawdopodobnie może sobie pozwolić na zabicie tagów, których jego prosty „parser” nie może zrozumieć.
Na przykład:
źródło
Jeśli chodzi o pytanie o metody RegExp do parsowania (x) HTML, odpowiedź dla wszystkich, którzy mówili o pewnych ograniczeniach, jest następująca: nie zostałeś wystarczająco wyszkolony, aby rządzić siłą tej potężnej broni, ponieważ NIKT nie mówił tutaj o rekurencji .
Pewien kolega z RegExp powiadomił mnie o tej dyskusji, która z pewnością nie jest pierwszą w Internecie na temat tego starego i gorącego tematu.
Po przeczytaniu niektórych postów, pierwszą rzeczą, jaką zrobiłem, było szukanie ciągu „? R” w tym wątku. Drugim było poszukiwanie „rekurencji”.
Nie, święta krowa, nie znaleziono dopasowania.
Ponieważ nikt nie wspomniał o głównym mechanizmie, na którym zbudowany jest parser, wkrótce zdałem sobie sprawę, że nikt nie rozumie.
Jeśli parser (x) HTML wymaga rekursji, parser RegExp bez rekurencji nie wystarczy do tego celu. To prosta konstrukcja.
Czarny RegExp sztuka jest trudna do opanowania , więc może istnieją dalsze możliwości pominęliśmy podczas próby i badania nasze osobiste rozwiązanie, aby uchwycić całą sieć w jednej ręce ... Cóż, jestem pewien o tym :)
Oto magiczny wzór:
Po prostu spróbuj.
Jest napisany jako ciąg PHP, więc modyfikator „s” sprawia, że klasy zawierają znaki nowej linii.
Oto przykładowa notatka do podręcznika PHP napisanego w styczniu: Odniesienie
(Uważaj, w tej notatce niewłaściwie użyłem modyfikatora „m”; powinien on zostać usunięty, mimo że jest odrzucony przez silnik RegExp, ponieważ nie użyto zakotwiczenia ^ ani $).
Teraz możemy mówić o granicach tej metody z bardziej świadomego punktu widzenia:
W każdym razie jest to tylko wzorzec RegExp, ale ujawnia on możliwość opracowania wielu potężnych implementacji.
Napisałem ten wzorzec, aby zasilić parser rekurencyjnego descentowania silnika szablonu, który zbudowałem w swoim frameworku, a jego wydajność jest naprawdę świetna, zarówno w czasie wykonywania, jak i w użyciu pamięci (nie ma to nic wspólnego z innymi silnikami szablonów, które używają tej samej składni).
źródło
Jak wiele osób już zauważyło, HTML nie jest zwykłym językiem, co może bardzo utrudniać jego analizę. Moim rozwiązaniem jest przekształcenie go w zwykły język za pomocą uporządkowanego programu, a następnie użycie analizatora składni XML do wykorzystania wyników. Jest na to wiele dobrych opcji. Mój program jest napisany przy użyciu Java z biblioteką jtidy, aby przekształcić HTML na XML, a następnie Jaxen na xpath w wynik.
źródło
Części wyjaśnione:
<
: postać początkowa\s*
: może zawierać białe spacje przed nazwą znacznika (brzydkie, ale możliwe).(\w+)
: tagi mogą zawierać litery i cyfry (h1). Cóż,\w
pasuje również do „_”, ale chyba nie zaszkodzi. Jeśli ciekawi, użyj zamiast tego ([a-zA-Z0-9] +).[^/>]*
: cokolwiek oprócz>
i/
do zamknięcia>
>
: zamykanie>
NIE POWIĄZANE
A dla ludzi, którzy nie doceniają wyrażeń regularnych, mówiąc, że są tak potężni jak zwykłe języki:
a n ba n ba n, który nie jest regularny i nawet pozbawiony kontekstu, można dopasować
^(a+)b\1b\1$
Odwołanie zwrotne FTW !
źródło
O(MN)
(M oznacza długość wyrażenia regularnego, N oznacza długość tekstu). Odwołania wsteczne są jedną z przyczyn tego. Implementacja w awk nie ma odnośników zwrotnych i dopasowuje wszystko wO(MN)
czasie.Jeśli po prostu próbujesz znaleźć te tagi (bez ambicji parsowania), wypróbuj to wyrażenie regularne:
Napisałem to w 30 sekund i przetestowałem tutaj: http://gskinner.com/RegExr/
Pasuje do typów wspomnianych tagów, ignorując typy, które chcesz zignorować.
źródło
\/>
zamiast\\>
.\>
to miałem na myśli; Nigdy nie zamierzałem edytować wyrażenia regularnego mojego oryginalnego postu.\/
, ponieważ zrobiłoby to dokładnie odwrotność wymagań. Może myślałem, że oferujesz negatywny wzorzec filtra.Wydaje mi się, że próbujesz dopasować tagi bez znaku „/” na końcu. Spróbuj tego:
źródło
Prawdą jest, że podczas programowania najlepiej jest używać dedykowanych analizatorów składni i interfejsów API zamiast wyrażeń regularnych podczas obsługi HTML, szczególnie jeśli dokładność jest najważniejsza (np. Jeśli przetwarzanie może mieć wpływ na bezpieczeństwo). Nie przypisuję jednak poglądu dogmatycznego, że znaczniki w stylu XML nigdy nie powinny być przetwarzane za pomocą wyrażeń regularnych. Zdarzają się przypadki, gdy wyrażenia regularne są doskonałym narzędziem do tego zadania, na przykład podczas jednorazowych edycji w edytorze tekstu, naprawiania uszkodzonych plików XML lub radzenia sobie z formatami plików, które wyglądają, ale nie są całkiem XML. Należy pamiętać o pewnych problemach, ale nie są one nie do pokonania, a nawet niekoniecznie istotne.
Zwykłe wyrażenie regularne
<([^>"']|"[^"]*"|'[^']*')*>
jest zwykle wystarczające, w przypadkach takich jak te, o których właśnie wspomniałem. Jest to naiwne rozwiązanie, biorąc pod uwagę wszystko, ale poprawnie dopuszcza niezakodowane>
symbole w wartościach atrybutów. Jeśli szukasz np.table
Tagu, możesz go dostosować jako</?table\b([^>"']|"[^"]*"|'[^']*')*>
.Aby dać wyobrażenie o tym, jak mógłby wyglądać bardziej „zaawansowany” regex HTML, poniższe czynności wykonują dość godne szacowania działania przeglądarki i algorytm analizy HTML5:
Poniższa definicja odpowiada dość ścisłej definicji tagów XML (chociaż nie uwzględnia pełnego zestawu znaków Unicode dozwolonych w nazwach XML):
To prawda, że nie uwzględniają kontekstu otaczającego i kilku przypadków krawędzi, ale nawet z takimi rzeczami można sobie poradzić, jeśli naprawdę chcesz (np. Przeszukując dopasowania innego wyrażenia regularnego).
Na koniec użyj najbardziej odpowiedniego narzędzia do zadania, nawet w przypadkach, gdy narzędzie to jest wyrażeniem regularnym.
źródło
Chociaż nie jest odpowiednie i skuteczne używanie do tego celu wyrażeń regularnych, czasami wyrażenia regularne zapewniają szybkie rozwiązania prostych problemów z dopasowaniem i moim zdaniem używanie wyrażeń regularnych w trywialnych pracach nie jest zbyt trudne.
Istnieje ostateczny post na blogu o dopasowaniu najbardziej wewnętrznych elementów HTML napisany przez Stevena Levithana.
źródło