Jeden błąd widzę ludzi co nad i znowu próbuje zanalizować XML lub HTML z regex. Oto kilka powodów, dla których parsowanie XML i HTML jest trudne:
Ludzie chcą traktować plik jako ciąg wierszy, ale jest to poprawne:
<tag
attr="5"
/>
Ludzie chcą traktować tag <lub <jako początek tagu, ale takie rzeczy istnieją na wolności:
<img src="imgtag.gif" alt="<img>" />
Ludzie często chcą dopasowywać tagi początkowe do tagów końcowych, ale XML i HTML pozwalają tagom się zawierać (których tradycyjne wyrażenia regularne w ogóle nie są w stanie obsłużyć):
<span id="outer"><span id="inner">foo</span></span>
Ludzie często chcą dopasować do treści dokumentu (np. Słynny problem „znajdź wszystkie numery telefonów na danej stronie”), ale dane mogą zostać oznaczone (nawet jeśli wyglądają normalnie podczas przeglądania):
<span class="phonenum">(<span class="area code">703</span>)
<span class="prefix">348</span>-<span class="linenum">3020</span></span>
Komentarze mogą zawierać źle sformatowane lub niekompletne tagi:
<a href="foo">foo</a>
<!-- FIXME:
<a href="
-->
<a href="bar">bar</a>
O jakich innych problemach jesteś świadomy?
Odpowiedzi:
Oto kilka poprawnych poprawnych plików XML:
A ten mały pakiet radości jest poprawnym HTML:
Nie wspominając już o parsowaniu specyficznych dla przeglądarki nieprawidłowych konstrukcji.
Powodzenia przeciwko temu wyrażeniu!
EDYCJA (Jörg W Mittag): Oto kolejny fajny kawałek dobrze sformułowanego, poprawnego HTML 4.01:
źródło
Tak właściwie
nie jest poprawnym HTML-em i nie jest poprawnym XML-em.
To nie jest poprawny XML, ponieważ „<” i „>” nie są prawidłowymi znakami w ciągach atrybutów. Należy je zmienić za pomocą odpowiednich jednostek XML & lt; i>
Nie jest to również poprawny HTML, ponieważ krótki formularz zamykający nie jest dozwolony w HTML (ale jest poprawny w XML i XHTML). Znacznik „img” jest także znacznikiem niejawnie zamkniętym zgodnie ze specyfikacją HTML 4.01. Oznacza to, że ręczne zamknięcie jest w rzeczywistości nieprawidłowe i jest równoważne dwukrotnemu zamknięciu dowolnego innego znacznika.
Prawidłowa wersja w HTML to
a poprawna wersja w XHTML i XML to
Podany poniżej przykład jest również nieprawidłowy
To też nie jest poprawny HTML ani XML. Nazwa znacznika musi znajdować się tuż za „<”, chociaż atrybuty i zamykające „>” mogą znajdować się w dowolnym miejscu. Tak więc poprawny XML jest w rzeczywistości
A oto jeszcze jedna zabawniejsza: możesz faktycznie użyć „lub” jako znaku cudzysłowu
Wszystkie pozostałe powody, które zostały opublikowane, są poprawne, ale największym problemem podczas analizowania HTML jest to, że ludzie zwykle nie rozumieją poprawnie wszystkich reguł składni. Fakt, że twoja przeglądarka interpretuje tagoupoup jako HTML, nie oznacza, że faktycznie napisałeś prawidłowy HTML.
Edycja: I nawet stackoverflow.com zgadza się ze mną w sprawie definicji ważnej i niepoprawnej. Twój nieprawidłowy XML / HTML nie jest podświetlony, a moja poprawiona wersja to.
Zasadniczo XML nie jest analizowany za pomocą wyrażeń regularnych. Ale nie ma też powodu, aby to robić. Istnieje wiele, wiele parserów XML dla każdego języka. Masz wybór między parserami SAX, parserami DOM i parserami Pull. Wszystkie te są gwarantowane znacznie szybciej niż parsowanie z wyrażeniem regularnym, a następnie możesz użyć fajnych technologii, takich jak XPath lub XSLT, w powstałym drzewie DOM.
Moja odpowiedź brzmi zatem: nie tylko trudno jest analizować XML z wyrażeniami regularnymi, ale jest to również zły pomysł. Wystarczy użyć jednego z milionów istniejących parserów XML i skorzystać ze wszystkich zaawansowanych funkcji XML.
HTML jest po prostu zbyt trudny, aby nawet samemu parsować. Po pierwsze, składnia prawna zawiera wiele drobnych subtelności, o których być może nie jesteś świadomy, a po drugie, HTML na wolności jest po prostu ogromną śmierdzącą stertą (dostajesz mój dryf). Istnieje wiele bibliotek parserów Lax, które dobrze sobie radzą z obsługą HTML, takich jak zupa tagów, wystarczy ich użyć.
źródło
>
znak jest całkowicie poprawny w html stackoverflow.com/questions/94528/…Napisałem cały wpis na blogu na ten temat: Ograniczenia wyrażeń regularnych
Sedno problemu polega na tym, że HTML i XML są strukturami rekurencyjnymi, które wymagają mechanizmów zliczania w celu prawidłowego parsowania. Prawdziwe wyrażenie regularne nie jest w stanie zliczyć. Aby liczyć, musisz mieć gramatykę bezkontekstową.
Poprzedni akapit zawiera pewne zastrzeżenie. Niektóre implementacje wyrażeń regularnych obsługują teraz ideę rekurencji. Jednak gdy zaczniesz dodawać rekurencję do wyrażeń regularnych, naprawdę rozciągasz granice i powinieneś rozważyć parser.
źródło
Jednej nie ma na liście, że atrybuty mogą pojawiać się w dowolnej kolejności, więc jeśli wyrażenie regularne szuka linku z href „foo” i klasą „bar”, mogą występować w dowolnej kolejności i mieć dowolną liczbę innych rzeczy między nimi.
źródło
To zależy od tego, co rozumiesz przez „parsowanie”. Ogólnie mówiąc, XML nie może być analizowany przy użyciu wyrażenia regularnego, ponieważ gramatyka XML nie jest bynajmniej regularna. Krótko mówiąc, wyrażenia regularne nie mogą się liczyć (no cóż, wyrażenia regularne Perla mogą być w stanie policzyć rzeczy), więc nie można zrównoważyć tagów otwieranie-zamykanie.
źródło
Czy ludzie rzeczywiście popełniają błąd, używając wyrażenia regularnego, czy jest to po prostu wystarczająco dobre do zadania, które próbują osiągnąć?
Całkowicie się zgadzam, że analizowanie html i xml przy użyciu wyrażenia regularnego nie jest możliwe, ponieważ inni ludzie odpowiedzieli.
Jeśli jednak twoim wymaganiem nie jest parsowanie html / xml, ale tylko uzyskanie jednego małego fragmentu danych w „znanym dobrym” kawałku html / xml, być może wystarczające jest wyrażenie regularne lub nawet prostsze „podciąg”.
źródło
Ludzie zwykle domyślnie piszą chciwe wzory, co często prowadzi do nierozważnego przemyślenia. * Dzielenie dużych kawałków pliku na możliwie największy <foo>. * </foo>.
źródło
.*?<
, możesz to naprawić, używając negowanej klasy postaci, takiej jak[^<]*<
. (Zastrzeżenie: oczywiście nadal nie jest to niezawodne, o to właśnie chodzi).Kusi mnie, aby powiedzieć „nie wymyślaj od nowa koła”. Tyle że XML jest naprawdę, naprawdę złożony format. Więc może powinienem powiedzieć „nie wymyślaj ponownie synchrotronu”.
Być może prawidłowa fraza zaczyna się „gdy wszystko, co masz, to młotek…”. Wiesz, jak używać wyrażeń regularnych, wyrażenia regularne są dobre w analizie, więc po co zawracać sobie głowę nauką biblioteki parsowania XML?
Ponieważ parsowanie XML jest trudne . Wszelkie wysiłki zaoszczędzone przez to, że nie musisz nauczyć się korzystać z biblioteki parsowania XML, będą więcej niż nadrobione przez pracę twórczą i usuwanie błędów, które będziesz musiał zrobić. Dla własnego dobra „Google Library” w Google i wykorzystaj czyjąś pracę.
źródło
Wierzę, że ten klasyk zawiera informacje, których szukasz. Można znaleźć punkt w jednym z komentarzy tam:
Więcej informacji z Wikipedii: Chomsky Hierarchy
źródło
Myślę, że problemy sprowadzają się do:
Wyrażenie regularne jest prawie zawsze niepoprawne. Istnieją uzasadnione dane wejściowe, których nie uda się poprawnie dopasować. Jeśli pracujesz wystarczająco ciężko, możesz sprawić, by było w 99% poprawne lub 99,999%, ale uczynienie go w 100% poprawnym jest prawie niemożliwe, choćby z powodu dziwnych rzeczy, na które XML pozwala na używanie jednostek.
Jeśli wyrażenie regularne jest niepoprawne, nawet dla 0,00001% danych wejściowych, masz problem z bezpieczeństwem, ponieważ ktoś może odkryć dane wejściowe, które spowodują uszkodzenie aplikacji.
Jeśli wyrażenie regularne jest na tyle poprawne, że obejmuje 99,99% przypadków, będzie całkowicie nieczytelne i niemożliwe do utrzymania.
Jest bardzo prawdopodobne, że wyrażenie regularne będzie bardzo źle działać na plikach wejściowych średniej wielkości. Moje pierwsze spotkanie z XML polegało na zastąpieniu skryptu Perl, który (niepoprawnie) analizował przychodzące dokumenty XML odpowiednim parserem XML, i nie tylko zastąpiliśmy 300 linii nieczytelnego kodu 100 liniami, które każdy mógł zrozumieć, ale poprawiliśmy czas reakcji użytkownika od 10 sekund do około 0,1 sekundy.
źródło
Nie zgadzam się. Jeśli użyjesz rekurencyjnego w wyrażeniach regularnych, możesz łatwo znaleźć otwieranie i zamykanie tagów.
Tutaj pokazałem przykład wyrażenia regularnego, aby uniknąć błędów parsowania przykładów w pierwszej wiadomości.
źródło
Dałem uproszczoną odpowiedź na ten problem tutaj . Chociaż nie uwzględnia znaku 100%, wyjaśniam, jak to możliwe, jeśli chcesz wykonać pewne czynności związane z przetwarzaniem wstępnym.
źródło