Одна ошибка, которую я вижу, что люди делают снова и снова, это попытка разобрать XML или HTML с помощью регулярного выражения. Вот несколько причин, по которым сложно анализировать XML и HTML:
Люди хотят рассматривать файл как последовательность строк, но это действительно так:
<tag
attr="5"
/>
Люди хотят рассматривать тег <или <как начало тега, но такие вещи существуют в дикой природе:
<img src="imgtag.gif" alt="<img>" />
Люди часто хотят сопоставить начальные и конечные теги, но XML и HTML позволяют тегам содержать себя (что традиционные регулярные выражения вообще не могут обработать):
<span id="outer"><span id="inner">foo</span></span>
Люди часто хотят сопоставить содержимое документа (например, известную проблему «найти все номера телефонов на данной странице»), но данные могут быть размечены (даже если они выглядят нормальными при просмотре):
<span class="phonenum">(<span class="area code">703</span>)
<span class="prefix">348</span>-<span class="linenum">3020</span></span>
Комментарии могут содержать плохо отформатированные или неполные теги:
<a href="foo">foo</a>
<!-- FIXME:
<a href="
-->
<a href="bar">bar</a>
Какие еще ошибки вы знаете?
Ответы:
Вот забавный действительный XML для вас:
И этот маленький пучок радости является действительным HTML:
Не говоря уже о браузерском разборе на наличие недействительных конструкций.
Удачи в борьбе с этим!
РЕДАКТИРОВАТЬ (Jörg W Mittag): Вот еще один хороший кусок правильно оформленного, верного HTML 4.01:
источник
Фактически
не является допустимым HTML, а также не является допустимым XML.
Это недопустимый XML, потому что '<' и '>' не являются допустимыми символами внутри строк атрибута. Их необходимо экранировать, используя соответствующие объекты XML & lt; и & gt;
Это также недопустимый HTML, поскольку в HTML недопустима короткая закрывающая форма (но она верна в XML и XHTML). Тег 'img' также является неявно закрытым тегом согласно спецификации HTML 4.01. Это означает, что закрытие вручную на самом деле неверно и эквивалентно закрытию любого другого тега дважды.
Правильная версия в HTML
и правильная версия в XHTML и XML
Приведенный ниже пример также недействителен
Это не допустимый HTML или XML либо. Имя тега должно быть сразу за «<», хотя атрибуты и закрывающий «>» могут быть где угодно. Таким образом, действительный XML на самом деле
И вот еще один более забавный: вы можете выбрать «или» в качестве символа цитирования атрибута.
Все остальные причины, которые были опубликованы, верны, но самая большая проблема при разборе HTML заключается в том, что люди обычно не понимают все правила синтаксиса правильно. Тот факт, что ваш браузер интерпретирует ваш tagoup как HTML, не означает, что вы действительно написали правильный HTML.
Редактировать: И даже stackoverflow.com соглашается со мной относительно определения действительных и недействительных. Ваш неверный XML / HTML не выделен, а моя исправленная версия -.
По сути, XML не предназначен для анализа с помощью регулярных выражений. Но нет также причин для этого. Существует множество синтаксических анализаторов XML для каждого языка. У вас есть выбор между парсерами SAX, DOM и парсерами Pull. Все они гарантированно будут выполняться намного быстрее, чем синтаксический анализ с помощью регулярного выражения, и тогда вы можете использовать классные технологии, такие как XPath или XSLT, в получающемся дереве DOM.
Поэтому я отвечаю: не только сложно анализировать XML с помощью регулярных выражений, но и это плохая идея. Просто используйте один из миллионов существующих анализаторов XML и воспользуйтесь всеми расширенными функциями XML.
HTML слишком сложен, чтобы даже пытаться анализировать его самостоятельно. Во-первых, юридический синтаксис имеет много мелких тонкостей, о которых вы, возможно, не знаете, а во-вторых, HTML в дикой природе - это просто огромная вонючая куча (вы понимаете, мой дрейф) Существует множество библиотек синтаксического анализатора, которые хорошо справляются с обработкой HTML, например супа тегов, просто используйте их.
источник
>
знак полностью действителен в html stackoverflow.com/questions/94528/…Я написал целую запись в блоге на эту тему: Ограничения регулярных выражений
Суть проблемы в том, что HTML и XML являются рекурсивными структурами, для правильного анализа которых требуются механизмы подсчета. Истинное регулярное выражение не в состоянии считать. Вы должны иметь контекстно-свободную грамматику, чтобы считать.
Предыдущий абзац идет с небольшим предостережением. Некоторые реализации регулярных выражений теперь поддерживают идею рекурсии. Однако, как только вы начинаете добавлять рекурсию в свои выражения регулярных выражений, вы действительно расширяете границы и должны рассмотреть парсер.
источник
Один недостаток, которого нет в вашем списке, заключается в том, что атрибуты могут появляться в любом порядке, поэтому, если ваше регулярное выражение ищет ссылку с href "foo" и классом "bar", они могут приходить в любом порядке и иметь любое количество других вещи между ними.
источник
Это зависит от того, что вы подразумеваете под "разбором". Вообще говоря, XML не может быть проанализирован с помощью регулярных выражений, поскольку грамматика XML ни в коем случае не является регулярной. Проще говоря, регулярные выражения не могут сосчитать (ну, регулярные выражения Perl могут фактически подсчитывать вещи), поэтому вы не можете сбалансировать открытые и закрытые теги.
источник
Люди на самом деле делают ошибку, используя регулярные выражения, или это просто достаточно хорошо для задачи, которую они пытаются достичь?
Я полностью согласен с тем, что синтаксический анализ html и xml с использованием регулярных выражений невозможен, поскольку другие люди ответили.
Однако, если ваше требование состоит не в разборе html / xml, а в том, чтобы просто получить один маленький бит данных в «хорошо известном» бите html / xml, тогда, возможно, достаточно регулярного выражения или даже еще более простой «подстроки».
источник
Как правило, люди по умолчанию пишут жадные шаблоны, что часто приводит к непродуманному. * Превращению больших кусков файла в максимально возможный <foo>. * </ Foo>.
источник
.*?<
, вы можете исправить это, используя отрицательный класс символов вроде[^<]*<
. (Отказ от ответственности: очевидно, что это все еще не надежно, что является вопросом вопроса.)Я испытываю желание сказать «не изобретай велосипед». За исключением того, что XML действительно, действительно сложный формат. Поэтому, может быть, я должен сказать «не изобретать синхротрон».
Возможно, правильное клише начинается «когда все, что у вас есть, это молоток ...» Вы знаете, как использовать регулярные выражения, регулярные выражения хороши при разборе, так зачем же изучать библиотеку разбора XML?
Потому что разбирать XML сложно . Любые усилия, которые вы сэкономите, не изучая использование библиотеки синтаксического анализа XML, будут более чем компенсированы количеством творческой работы и выявлением ошибок, которые вам придется сделать. Ради себя, Google "XML-библиотека" и использовать чужую работу.
источник
Я считаю, что у этого классика есть информация, которую вы ищете. Вы можете найти точку в одном из комментариев:
Еще немного информации из Википедии: Хомская Иерархия
источник
Я думаю, что проблемы сводятся к:
Регулярное выражение почти всегда неверно. Существуют допустимые входные данные, которые не могут быть правильно сопоставлены. Если вы достаточно усердно работаете, вы можете сделать это на 99% правильным, или на 99,999%, но сделать это на 100% правильным практически невозможно, хотя бы из-за странных вещей, которые XML допускает с помощью сущностей.
Если регулярное выражение неверно, даже для 0,00001% входов, у вас есть проблемы с безопасностью, потому что кто-то может обнаружить один вход, который сломает ваше приложение.
Если регулярное выражение достаточно корректно, чтобы охватить 99,99% случаев, оно будет полностью нечитаемым и недостижимым.
Весьма вероятно, что регулярные выражения будут очень плохо работать с входными файлами среднего размера. Мое самое первое знакомство с XML состояло в том, чтобы заменить скрипт Perl, который (неправильно) анализировал входящие XML-документы, соответствующим анализатором XML, и мы не только заменили 300 строк нечитаемого кода на 100 строк, которые каждый мог понять, но мы улучшили время отклика пользователей. от 10 секунд до 0,1 секунды.
источник
Я не согласен. Если вы будете использовать рекурсивные выражения в регулярных выражениях, вы можете легко найти открытые и закрытые теги.
Здесь я показал пример регулярного выражения, чтобы избежать ошибок разбора примеров в первом сообщении.
источник
Я дал упрощенный ответ на эту проблему здесь . Хотя это и не учитывает 100% отметки, я объясняю, как это возможно, если вы готовы выполнить некоторую предварительную обработку.
источник