Używanie wyrażeń regularnych do analizy HTML: dlaczego nie?

Wydaje się, że każde pytanie w stoskoverflow, gdzie asker używa regex do przechwytywania informacji z HTML, nieuchronnie będzie miało "odpowiedź", która mówi, aby nie używać regex do analizowania HTML.

Dlaczego nie? Zdaję sobie sprawę, że istnieją "prawdziwe" parsery HTML, takie jak Beautiful Soup, I jestem pewien, że są potężne i użyteczne, ale jeśli robisz coś prostego, szybkiego lub brudnego, to po co zawracać sobie głowę używaniem czegoś tak skomplikowanego, gdy kilka wyrażeń regex działa dobrze?

Ponadto, czy jest coś fundamentalnego, czego nie rozumiem w regex, co czyni je złym wyborem do parsowania w ogóle?

Author: Andy Lester, 2009-02-26

18 answers

Całe parsowanie HTML nie jest możliwe z wyrażeniami regularnymi, ponieważ zależy to od dopasowania znacznika otwarcia i zamknięcia, co nie jest możliwe z wyrażeniami regularnymi.

Wyrażenia regularne mogą pasować tylko do języków regularnych , ale HTML jest językiem wolnym od kontekstu , A nie językiem regularnym (jak zauważył @ StefanPochmann, języki regularne są również wolne od kontekstu, więc bez kontekstu nie musi oznaczać, że nie jest regularny). Jedyną rzeczą, którą można zrobić z wyrażeń regularnych na HTML jest heurystyka, ale to nie będzie działać na każdy warunek. Powinno być możliwe przedstawienie pliku HTML, który będzie błędnie dopasowany przez dowolne wyrażenie regularne.

 195
Author: Johannes Weiss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-09 16:16:27

Dla quickndirty regexp będzie dobrze. Ale podstawową rzeczą jest to, że jest niemożliwe skonstruowanie wyrażenia regularnego, które będzie poprawnie analizować HTML.

Powodem jest to, że wyrażenia regularne nie mogą obsługiwać arbitralnie zagnieżdżonych wyrażeń. Zobacz czy wyrażenia regularne mogą być używane do dopasowywania zagnieżdżonych wzorców?

 32
Author: kmkaplan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:15

(z http://htmlparsing.com/regexes )

Powiedz, że masz plik HTML, z którego próbujesz wyodrębnić adresy URL tagi.

<img src="http://example.com/whatever.jpg">

Więc piszesz regex jak ten w Perlu:

if ( $html =~ /<img src="(.+)"/ ) {
    $url = $1;
}

W tym przypadku, $url będzie rzeczywiście zawierać http://example.com/whatever.jpg. Ale co się dzieje, gdy zaczynasz otrzymywać HTML w ten sposób:

<img src='http://example.com/whatever.jpg'>

Lub

<img src=http://example.com/whatever.jpg>

Lub

<img border=0 src="http://example.com/whatever.jpg">

Lub

<img
    src="http://example.com/whatever.jpg">

Albo zaczynasz dostawać fałszywe alarmy od

<!-- // commented out
<img src="http://example.com/outdated.png">
-->

Wygląda tak proste i może to być proste dla pojedynczego, niezmiennego pliku, ale dla wszystkiego, co zamierzasz robić na dowolnych danych HTML, wyrażenia regularne są tylko przepisem na przyszłe bóle serca.

 18
Author: Andy Lester,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 17:07:31

Jeśli chodzi o parsowanie, wyrażenia regularne mogą być przydatne na etapie" analizy leksykalnej " (lexer), gdzie dane wejściowe są podzielone na tokeny. Jest to mniej przydatne w rzeczywistym etapie "zbuduj drzewo parsowania".

Dla parsera HTML, spodziewałbym się, że akceptuje tylko dobrze uformowany HTML, a to wymaga możliwości wykraczających poza to, co może zrobić Wyrażenie regularne (nie mogą "policzyć" i upewnić się, że dana liczba elementów otwierających jest zrównoważona przez tę samą liczbę elementów zamykających).

 16
Author: Vatine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 14:34:11

Dwa szybkie powody:

  • pisanie wyrażeń regularnych, które mogą przeciwstawić się złośliwemu wprowadzaniu jest trudne; o wiele trudniejsze niż używanie wbudowanego narzędzia
  • pisanie wyrażeń regularnych, które mogą działać ze śmiesznymi znacznikami, z którymi nieuchronnie utkniesz, jest trudne; o wiele trudniejsze niż użycie gotowego narzędzia

Odnośnie przydatności wyrażeń regularnych do parsowania w ogóle: nie są odpowiednie. Czy kiedykolwiek widziałeś rodzaje wyrażeń regularnych, których potrzebujesz do analizy większości języków?

 15
Author: Hank Gay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 14:29:02

Ponieważ istnieje wiele sposobów na "spieprzenie" HTML, które przeglądarki będą traktować w dość liberalny sposób, ale potrzeba sporo wysiłku, aby odtworzyć liberalne zachowanie przeglądarki, aby pokryć wszystkie przypadki wyrażeniami regularnymi, więc twoje Wyrażenie regularne nieuchronnie zawiedzie w niektórych szczególnych przypadkach, a to prawdopodobnie wprowadziłoby poważne luki w zabezpieczeniach w Twoim systemie.

 8
Author: Tamas Czinege,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 14:29:35

Problem polega na tym, że większość użytkowników, którzy zadają pytanie związane z HTML i regex, robi to, ponieważ nie mogą znaleźć własnego regex, który działa. Wtedy trzeba się zastanowić, czy wszystko byłoby łatwiejsze przy użyciu parsera DOM lub SAX lub czegoś podobnego. Są one zoptymalizowane i skonstruowane w celu pracy ze strukturami dokumentów podobnych do XML.

Oczywiście, istnieją problemy, które można łatwo rozwiązać za pomocą wyrażeń regularnych. Ale nacisk kładzie się na łatwo .

Jeśli chcesz znaleźć wszystkie adresy URL, które wyglądają jak http://.../, nie masz nic przeciwko wyrażeniom regularnym. Ale jeśli chcesz znaleźć wszystkie adresy URL, które są w elemencie a, który ma klasę "mylink", prawdopodobnie lepiej Użyj odpowiedniego parsera.

 7
Author: okoman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 21:09:31

Wyrażenia regularne nie zostały zaprojektowane do obsługi zagnieżdżonej struktury znaczników, a obsługa wszystkich możliwych przypadków brzegowych jest w najlepszym przypadku skomplikowana (w najgorszym niemożliwa).

 6
Author: Peter Boughton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 14:35:50

Wierzę, że odpowiedź leży w teorii obliczeń. Aby język był przetwarzany za pomocą regex, musi być z definicji "regularny" (link ). HTML nie jest językiem regularnym, ponieważ nie spełnia wielu kryteriów dla języka regularnego(wiele ma to wspólnego z wieloma poziomami zagnieżdżania charakterystycznymi dla kodu html). Jeśli interesuje Cię teoria obliczeń, polecam tę książkę .

 5
Author: taggers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 14:45:39

"to zależy" chociaż. To prawda, że wyrażenia regularne nie przetwarzają i nie mogą przetwarzać HTML z prawdziwą dokładnością, ze wszystkich powodów podanych tutaj. Jeśli jednak konsekwencje błędu (np. brak obsługi zagnieżdżonych tagów) są niewielkie, a wyrażenia regularne są bardzo wygodne w Twoim środowisku (np. gdy hakujesz Perla), śmiało.

Załóżmy, że jesteś, oh, może parsowanie stron internetowych, które link do witryny--być może znalazłeś je z Google link search--i chcesz szybki sposób, aby uzyskać ogólne idea kontekstu otaczają Twój link. Próbujesz uruchomić mały raport, który może ostrzec Cię o link spam, coś w tym stylu.

W takim przypadku, błędna interpretacja niektórych dokumentów nie będzie wielkim problemem. Nikt oprócz Ciebie nie zauważy błędów, a jeśli będziesz miał szczęście, będzie ich niewiele, które możesz śledzić indywidualnie.

Chyba mówię, że to kompromis. Czasami implementacja lub użycie poprawnego parsera-tak proste, jak to może być-może nie być warte zachodu jeśli dokładność nie jest krytyczna.

Uważaj na swoje założenia. Mogę wymyślić kilka sposobów, w jaki Skrót regexp może wystrzelić wstecz, jeśli próbujesz przeanalizować coś, co zostanie pokazane publicznie, na przykład.

 3
Author: catfood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 15:26:20

Są zdecydowanie przypadki, w których użycie wyrażenia regularnego do analizy niektórych informacji z HTML jest właściwym sposobem - zależy to w dużej mierze od konkretnej sytuacji.

Powyższy konsensus jest taki, że ogólnie jest to zły pomysł. Jeśli jednak struktura HTML jest znana (i prawdopodobnie się nie zmieni), to nadal jest to poprawne podejście.

 3
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-29 06:45:17

To wyrażenie pobiera atrybuty z elementów HTML. Obsługuje:

  • atrybuty nienotowane / cytowane,
  • pojedyncze / podwójne cytaty,
  • unikalne cytaty wewnątrz atrybutów,
  • spacje wokół znaków równości,
  • dowolna liczba atrybutów,
  • sprawdzaj tylko atrybuty wewnątrz znaczników,
  • escape comments, and
  • Zarządzaj różnymi cudzysłowami wewnątrz wartości atrybutu.

(?:\<\!\-\-(?:(?!\-\-\>)\r\n?|\n|.)*?-\-\>)|(?:<(\S+)\s+(?=.*>)|(?<=[=\s])\G)(?:((?:(?!\s|=).)*)\s*?=\s*?[\"']?((?:(?<=\")(?:(?<=\\)\"|[^\"])*|(?<=')(?:(?<=\\)'|[^'])*)|(?:(?!\"|')(?:(?!\/>|>|\s).)+))[\"']?\s*)

Sprawdź to . Działa lepiej z flagi "gisx", jak w demo.

 3
Author: Ivan Chaer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-11 02:46:13

Pamiętaj, że chociaż sam HTML nie jest regularny, części strony, na którą patrzysz , mogą być regularne.

Na przykład błąd zagnieżdżania znaczników <form>; jeśli strona działa poprawnie, użycie wyrażenia regularnego do przechwycenia <form> byłoby całkowicie uzasadnione.

Ostatnio robiłem skrobanie stron przy użyciu Selenium i wyrażeń regularnych. Uszło mi to na sucho, ponieważ dane, które chciałem umieścić w <form>, i umieścić w prostej tabeli format (więc mogłem nawet liczyć na<table>, <tr> i <td> być nie zagnieżdżonym-co jest w rzeczywistości bardzo nietypowe). W pewnym stopniu wyrażenia regularne były wręcz niezbędne, ponieważ część struktury, do której potrzebowałem dostępu, była ograniczona komentarzami. (Piękna zupa może dawać komentarze, ale trudno byłoby chwycić <!-- BEGIN --> i <!-- END --> bloki za pomocą pięknej zupy.)

Gdybym miał się martwić o zagnieżdżone tabele, moje podejście po prostu by nie zadziałało! I would have / align = "left" / Jednak nawet wtedy czasami można użyć wyrażenia regularnego, aby chwycić potrzebny kawałek,a następnie wywiercić stamtąd.

 2
Author: alpheus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 21:01:51

Właściwie, parsowanie HTML z regex jest całkowicie możliwe w PHP. Po prostu musisz przetworzyć cały łańcuch do tyłu używając strrpos, aby znaleźć < i powtórzyć regex stamtąd używając specyfikacji ungreedy za każdym razem, aby przejść przez zagnieżdżone tagi. Niezbyt fantazyjne i strasznie powolne w dużych rzeczach, ale użyłem go do własnego osobistego edytora szablonów na mojej stronie internetowej. W rzeczywistości nie analizowałem HTML, ale kilka niestandardowych znaczników, które zrobiłem do odpytywania wpisów w bazie danych, aby wyświetlić tabele danych (mój znacznik <#if()> mógł podświetlić wpisy specjalne w ten sposób). Nie byłem przygotowany, aby przejść do parsera XML tylko na kilka samodzielnie utworzonych tagów (z bardzo Nie-XML danych w nich) tu i tam.

Więc, mimo że to pytanie jest znacznie martwe, nadal pojawia się w wyszukiwarce Google. Przeczytałem go i pomyślałem "wyzwanie przyjęte" i skończyłem naprawiać mój prosty kod bez konieczności wymiany wszystkiego. Postanowiłem zaproponować inną opinię każdemu, kto szuka podobnego powodu. Ostatnia odpowiedź została wysłana 4 godziny ago więc to wciąż gorący temat.

 2
Author: Deji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-10 21:05:45

Próbowałem swoich sił w regex dla tego też. Jest to głównie przydatne do znajdowania fragmentów treści sparowanych z następnym tagiem HTML i nie szuka dopasowanie Zamknij tagi, ale będzie odbierać blisko tagi. Rzuć stos w swoim własnym języku, aby je sprawdzić.

Użyj z opcjami 'sx'. "g" too if you ' re feeling lucky:

(?P<content>.*?)                # Content up to next tag
(?P<markup>                     # Entire tag
  <!\[CDATA\[(?P<cdata>.+?)]]>| # <![CDATA[ ... ]]>
  <!--(?P<comment>.+?)-->|      # <!-- Comment -->
  </\s*(?P<close_tag>\w+)\s*>|  # </tag>
  <(?P<tag>\w+)                 # <tag ...
    (?P<attributes>
      (?P<attribute>\s+
# <snip>: Use this part to get the attributes out of 'attributes' group.
        (?P<attribute_name>\w+)
        (?:\s*=\s*
          (?P<attribute_value>
            [\w:/.\-]+|         # Unquoted
            (?=(?P<_v>          # Quoted
              (?P<_q>['\"]).*?(?<!\\)(?P=_q)))
            (?P=_v)
          ))?
# </snip>
      )*
    )\s*
  (?P<is_self_closing>/?)   # Self-closing indicator
  >)                        # End of tag

Ten jest przeznaczony dla Pythona (może działać dla innych języków, nie próbowałem, używa pozytywnego spojrzenia, negatywnego lookbehinds i nazwane backreferences). Podpory:

  • Open Tag - <div ...>
  • Zamknij Znacznik- </div>
  • komentarz - <!-- ... -->
  • CDATA - <![CDATA[ ... ]]>
  • Samozamykający Się Znacznik - <div .../>
  • Opcjonalne Wartości Atrybutów - <input checked>
  • Unquoted / Quoted Atrybut Values - <div style='...'>
  • Pojedyncze / Podwójne Cytaty- <div style="...">
  • Cytaty - <a title='John\'s Story'>
    (to nie jest poprawny HTML, ale jestem miłym facetem)
  • Spacje Wokół Równości Znaki - <a href = '...'>
  • Nazwane Przechwytywanie Interesujących Bitów

Jest również całkiem dobre o nie uruchamianie na zniekształconych tagów, jak gdy zapomnisz < lub >.

Jeśli twój smak regex obsługuje powtarzające się przechwytywania nazw, to jesteś złoty, ale Python re Nie (wiem, że regex tak, ale muszę użyć Pythona waniliowego). Oto co otrzymasz:

  • content - Cała zawartość aż do następnego tagu. Możesz to pominąć.
  • markup - The Cała metka ze wszystkim w środku.
  • comment - jeśli jest to komentarz, Treść komentarza.
  • cdata - jeśli jest <![CDATA[...]]>, zawartość CDATA.
  • close_tag - jeśli jest to znacznik close (</div>), nazwa znacznika.
  • tag - jeśli jest to otwarty znacznik (<div>), nazwa znacznika.
  • attributes - wszystkie atrybuty wewnątrz znacznika. Użyj tego, aby uzyskać wszystkie atrybuty, jeśli nie masz powtarzających się grup.
  • attribute - powtarzane, każdy atrybut.
  • attribute_name - powtarzane, każdy nazwa atrybutu.
  • attribute_value - powtarzane, każda wartość atrybutu. Dotyczy to również cytatów, jeśli były cytowane.
  • is_self_closing - to jest / jeśli jest to samozamykający się znacznik, w przeciwnym razie nic.
  • _q i _v - zignoruj je; są używane wewnętrznie do backreferencji.

Jeśli twój silnik regex nie obsługuje powtarzających się przechwytywań nazw, istnieje sekcja wywołana, której możesz użyć, aby uzyskać każdy atrybut. Po prostu uruchom ten regex na grupie attributes, aby uzyskać każdy attribute, attribute_name i attribute_value z tego.

Demo tutaj: https://regex101.com/r/mH8jSu/11

 2
Author: Hounshell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-28 21:48:55

HTML / XML jest podzielony na znaczniki i treść.
Regex jest przydatny tylko podczas parsowania znaczników leksykalnych.
Myślę, że można wydedukować treść.
To byłby dobry wybór dla parsera saksofonu.
Tagi i treści mogą być dostarczane do użytkownika
zdefiniowana funkcja, gdzie zagnieżdżanie / zamykanie elementów
można śledzić.

Jeśli chodzi o parsowanie znaczników, można to zrobić za pomocą
regex i używane do usuwania znaczników z dokumentu.

Przez lata testów, znalazłem sekret
sposób przeglądarki parsują znaczniki, zarówno dobrze jak i źle uformowane.

Normalne elementy są przetwarzane w tej postaci:

Rdzeń tych znaczników używa tego wyrażenia regularnego

 (?:
      " [\S\s]*? " 
   |  ' [\S\s]*? ' 
   |  [^>]? 
 )+

Zauważysz to [^>]? jako jedną z przemian.
Będzie to pasowało do niezrównoważonych cytatów ze źle uformowanych tagów.

Jest to również najbardziejkorzeń wszelkiego zła do wyrażeń regularnych.
Sposób, w jaki jest używany, wywoła bump-along, aby zaspokoić jego chciwość, must-match
kontener ilościowy.

Jeśli jest używany pasywnie, nigdy nie ma problemu.
Ale jeśli wymusisz coś dopasować, przeplatając to z
poszukiwana para atrybutów / wartości i nie zapewnia odpowiedniej ochrony
z backtrackingu, to wymykający się spod kontroli koszmar.

Jest to ogólna forma dla zwykłych starych tagów.
Zauważ, że [\w:] reprezentuje nazwę tagu ?
W rzeczywistości prawne znaki reprezentujące tag nazwa
to niesamowita lista znaków Unicode.

 <     
 (?:
      [\w:]+ 
      \s+ 
      (?:
           " [\S\s]*? " 
        |  ' [\S\s]*? ' 
        |  [^>]? 
      )+
      \s* /?
 )
 >

Idąc dalej, widzimy również, że po prostu nie można wyszukać określonego tagu
bez parsowania wszystkich tagów.
To znaczy można, ale musiałoby użyć kombinacji
czasowniki takie jak (*SKIP) (*FAIL), ale nadal wszystkie znaczniki muszą być analizowane.

Powodem jest to, że składnia tagów może być ukryta wewnątrz innych tagów itp..

Więc, aby pasywnie parsować wszystkie znaczniki, regex jest potrzebny jak ten poniżej.
Ten konkretny pasuje invisible content, jak również.

Jako nowy HTML lub xml lub jakikolwiek inny twórz nowe konstrukcje, po prostu dodaj go jako
jedna z przemian.


web page note-nigdy nie widziałem strony internetowej (lub xhtml / xml), że to
miałem z tym problem. Jak znajdziesz, daj mi znać.

notka o wydajności-jest szybka. Jest to najszybszy parser tagów jaki widziałem
(może być szybciej, kto wie).
Mam kilka wersje szczegółowe. Jest również doskonały jako skrobak
(jeśli jesteś typem hands-on).


Complete raw regex

<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>

Sformatowany wygląd

 <
 (?:
      (?:
           (?:
                # Invisible content; end tag req'd
                (                             # (1 start)
                     script
                  |  style
                  |  object
                  |  embed
                  |  applet
                  |  noframes
                  |  noscript
                  |  noembed 
                )                             # (1 end)
                (?:
                     \s+ 
                     (?>
                          " [\S\s]*? "
                       |  ' [\S\s]*? '
                       |  (?:
                               (?! /> )
                               [^>] 
                          )?
                     )+
                )?
                \s* >
           )

           [\S\s]*? </ \1 \s* 
           (?= > )
      )

   |  (?: /? [\w:]+ \s* /? )
   |  (?:
           [\w:]+ 
           \s+ 
           (?:
                " [\S\s]*? " 
             |  ' [\S\s]*? ' 
             |  [^>]? 
           )+
           \s* /?
      )
   |  \? [\S\s]*? \?
   |  (?:
           !
           (?:
                (?: DOCTYPE [\S\s]*? )
             |  (?: \[CDATA\[ [\S\s]*? \]\] )
             |  (?: -- [\S\s]*? -- )
             |  (?: ATTLIST [\S\s]*? )
             |  (?: ENTITY [\S\s]*? )
             |  (?: ELEMENT [\S\s]*? )
           )
      )
 )
 >
 2
Author: sln,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-15 22:26:23

Wyrażenia regularne nie są wystarczająco potężne dla takiego języka jak HTML. Oczywiście, istnieje kilka przykładów, w których można używać wyrażeń regularnych. Ale na ogół nie jest to odpowiednie do parsowania.

 1
Author: Gumbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 14:33:51

Wiesz...jest w tobie dużo mentalności, nie możesz tego zrobić i myślę, że wszyscy po obu stronach ogrodzenia mają rację, a my nie. Ty możesz to zrobić, ale wymaga to trochę więcej przetwarzania niż tylko uruchomienie jednego wyrażenia regularnego. Weź to (napisałem to w ciągu godziny) jako przykład. Zakłada, że HTML jest całkowicie poprawny, ale w zależności od tego, jakiego języka używasz do zastosowania wyżej wymienionych regex, możesz zrobić pewne poprawki HTML, aby upewnić się, że uda się. Na przykład usunięcie znaczników zamykających, które nie powinny tam być: </img> na przykład. Następnie dodaj zamykający pojedynczy ukośnik HTML do elementów, których brakuje, itp.

Użyłbym tego w kontekście pisania biblioteki, która pozwoliłaby mi na pobieranie elementów HTML, podobnie jak JavaScript [x].getElementsByTagName(), na przykład. Po prostu połączyłem funkcjonalność, którą napisałem w sekcji DEFINE regex i użyłem jej do wchodzenia do drzewa z żywioły, pojedynczo.

Czy to będzie ostateczna 100% odpowiedź na walidację HTML? Nie. Ale to początek i przy odrobinie więcej pracy można to zrobić. Jednak próba zrobienia tego wewnątrz jednego wykonania regex nie jest ani praktyczna, ani skuteczna.

 0
Author: Erutan409,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 15:03:21