Я согласен, что правильный инструмент для синтаксического анализа XML и , особенно HTML , является синтаксическим анализатором, а не механизмом регулярных выражений. Однако, как указывали другие, иногда использование регулярного выражения выполняется быстрее, проще и выполняется, если вы знаете формат данных.
Microsoft фактически имеет раздел Рекомендации по регулярным выражениям в .NET Framework и, в частности, говорит о . Рассмотрим [вход] источника входного сигнала .
Регулярные выражения имеют ограничения, но вы считали следующее?
.NET framework уникален, когда речь заходит о регулярных выражениях в том, что он поддерживает Определения балансировочной группы .
По этой причине я считаю, что вы можете анализировать XML с помощью регулярных выражений. Обратите внимание, однако, что он должен быть достоверным. XML ( браузеры очень прощают HTML и допускают плохой синтаксис XML внутри HTML ). Это возможно, так как «Определение балансировки группы» позволит механизму регулярных выражений действовать как КПК.
Цитата из статьи 1, процитированной выше:
.NET Regular Expression Двигатель
Как описано выше, правильно сбалансированные конструкции не могут быть описаны регулярным выражением. Тем не менее, механизм регулярного выражения .NET предоставляет несколько конструкций, которые позволяют распознавать сбалансированные конструкции.
(?
- выталкивает захваченный результат в стек захвата с помощью группы имен.) (?<-group>)
- отображает верхний захват с группой имен с захвата stack.(?(group)yes|no)
- соответствует дате, если существует группа с группой имен, в противном случае не соответствует какой-либо детали.Эти конструкции допускают регулярную .NET выражение для подражания ограниченному КПК, по существу позволяя простые версии операций стека: push, pop и empty. Простые операции в значительной степени эквивалентны приращению, уменьшению и сравнению с нулем соответственно. Это позволяет механизму регулярного выражения .NET распознавать подмножество контекстно-свободных языков, в частности тех, которые требуют простого счетчика. Это, в свою очередь, позволяет нетрадиционным регулярным выражениям .NET распознавать индивидуально правильно сбалансированные конструкции.
blockquote>Рассмотрим следующее регулярное выражение:
(?=
) (?> | <[^>]*/> | (?
<(?!/)[^>]*[^/]>) | (?<-opentag>[^>]*[^/]>) | [^<>]* )* (?(opentag)(?!)) Использовать флаги :
- Singleline
- IgnorePatternWhitespace (необязательно, если вы сбрасываете регулярное выражение и удаляете все пробелы)
- IgnoreCase (необязательно)
Объяснение регулярного выражения (inline)
(?=
) # match start with
# atomic group / don't backtrack (faster) | # match xml / html comment <[^>]*/> | # self closing tag (?
<(?!/)[^>]*[^/]>) | # push opening xml tag (?<-opentag>[^>]*[^/]>) | # pop closing xml tag [^<>]* # something between tags )* # match as many xml tags as possible (?(opentag)(?!)) # ensure no 'opentag' groups are on stack Вы можете попробовать это на A Better .NET Regular Expression Tester .
Я использовал источник выборки:
- stuff...
- more stuff
still more
- Another >ul<, oh my!
- ...
Это нашло совпадение:
- stuff...
- more stuff
still more
- Another >ul<, oh my!
- ...
, хотя оно получилось так:
- stuff...
- more stuff
still more
- Another >ul<, oh my!
- ...
Наконец, Мне очень понравилась статья Джеффа Этвуда: Parsing Html Путь Ктулху . Забавно, он цитирует ответ на этот вопрос, который в настоящее время имеет более 4 кв голосов.
Это не отвечает на весь вопрос, но что касается написания кода, который вы не сможете прочитать за пару дней, вот несколько языков, которые побудят вас писать короткий, практически нечитаемый код:
В чем секрет Java копирования переменной только в одну строку, не беспокоясь о шинах и памяти? Ответ: код преобразуется в код большего размера. То же самое для всех когда-либо изобретенных языков.
Perl имеет множество односимвольных специальных переменных, которые предоставляют множество сокращений, например $.
$ _
$ @
$ /
$ 1
и т. Д. Я думаю, что это в сочетании со встроенными регулярными выражениями позволяет писать очень сжатый, но нечитаемый код.
Специальные переменные Perl ($ _, $., $ / И т. Д.) Часто можно использовать для сокращения кода (и более запутанный).
Я бы предположил, что "секрет" заключается в предоставлении родных операций для часто повторяющихся задач.
В той области, для которой изначально был задуман perl, вам часто приходится
и perl предоставляет простые операторы для выполнения этих задач. Короткие имена переменных и использование значений по умолчанию для многих вещей - это просто подливка.
Также perl не был первым языком, который пошел по этому пути. Многие возможности perl были украдены в более или менее целостном виде (или часто слегка улучшены) из sed и awk и различных оболочек. Молодец Ларри.
Конечно, perl не был последним, кто пошел по этому пути, вы найдете похожие возможности в python, php, ruby и .... Людям нравились результаты, и они не собирались отказываться от них только для того, чтобы получить более регулярный синтаксис.
Большинство людей не понимают смысла большей части синтаксиса Perl и операторов по умолчанию. Perl в значительной степени является языком "DWIM" (делай то, что я имею в виду). Одна из основных целей его разработки - "сделать обычные вещи простыми, а трудные - возможными".
В рамках этой цели разработчики Perl говорят о кодировании синтаксиса по Хаффману и думают о том, что людям нужно делать, вместо того, чтобы просто давать им низкоуровневые примитивы. То, что вы делаете часто, должно занимать наименьшее количество символов, а функции должны вести себя как наиболее распространенное поведение. Это позволяет сэкономить довольно много работы.
Например, split имеет много значений по умолчанию, потому что есть некоторые случаи использования, когда оставление чего-либо без аргументов используется как обычный случай. Без аргументов, split
разбивает $_
на пробельные символы, потому что это очень распространенное использование.
my @bits = split;
Чуть менее распространенный, но все же частый случай - разбить $_
на что-то еще, поэтому есть немного более длинная версия этого:
my @bits = split /:/;
И, если вы хотели явно указать источник данных, вы можете указать и переменную:
my @bits = split /:/, $line;
Думайте об этом, как вы обычно поступаете в жизни. Если у вас есть обычная задача, которую вы часто выполняете, например, разговор с барменом, у вас есть сокращение для нее, которое охватывает обычный случай:
Обычный
Если вам нужно сделать что-то, немного отличающееся, вы немного расширяете это:
Обычный, но с луком
Но вы всегда можете отметить специфику
Грязный мартини Bombay Sapphire, взболтанный, а не перемешанный
Подумайте об этом в следующий раз, когда будете просматривать веб-сайт. Сколько кликов вам нужно, чтобы выполнить обычные действия? Почему одни сайты просты в использовании, а другие - нет? Чаще всего хорошие сайты требуют от вас минимум усилий для выполнения обычных действий. В отличие от моего банка, который требует не менее 13 щелчков мыши для оплаты счета по кредитной карте. Это должно быть очень просто - дать им денег. :)
.Есть ряд факторов, которые делают Perl хорошим для игры в код:
$_
, если не указан аргумент. (Некоторые действуют
на @_
.)split
), часто имеют значения по умолчанию, которые
позволяют опустить некоторые аргументы или даже все. <>
. map
и grep
Кроме того, без строгих операторов (которые по умолчанию выключены):
undef
становится либо 0
, либо ''
в зависимости от контекста. Теперь, когда с этим покончено, позвольте мне прояснить один момент:
Гольф - это игра.
Здорово стремиться к тому уровню perl-фу, который позволяет вам быть хорошим игроком, но во имя $DIETY
не играйте в гольф реальным кодом. Во-первых, это ужасная трата времени. Вы можете потратить час на то, чтобы убрать несколько символов. Гофрированный код хрупок: он почти всегда делает серьезные допущения и легкомысленно игнорирует проверку ошибок. Настоящий код не может позволить себе быть таким небрежным. Наконец, вашей целью как программиста должно быть написание ясного, надежного и удобного в обслуживании кода. В программировании есть поговорка: Всегда пишите свой код так, как будто человек, который будет его сопровождать, - жестокий социопат, который знает, где вы живете.
Так что, во что бы то ни стало, начинайте играть в гольф; но осознавайте, что это всего лишь игра, и относитесь к этому как к таковой.