В чем секрет того, что Perl делает так мало кода?

Я согласен, что правильный инструмент для синтаксического анализа 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 кв голосов.

13
задан Cœur 27 October 2018 в 09:31
поделиться

7 ответов

Это не отвечает на весь вопрос, но что касается написания кода, который вы не сможете прочитать за пару дней, вот несколько языков, которые побудят вас писать короткий, практически нечитаемый код:

8
ответ дан 1 December 2019 в 17:23
поделиться

В чем секрет Java копирования переменной только в одну строку, не беспокоясь о шинах и памяти? Ответ: код преобразуется в код большего размера. То же самое для всех когда-либо изобретенных языков.

-2
ответ дан 1 December 2019 в 17:23
поделиться

Perl имеет множество односимвольных специальных переменных, которые предоставляют множество сокращений, например $. $ _ $ @ $ / $ 1 и т. Д. Я думаю, что это в сочетании со встроенными регулярными выражениями позволяет писать очень сжатый, но нечитаемый код.

7
ответ дан 1 December 2019 в 17:23
поделиться

Специальные переменные Perl ($ _, $., $ / И т. Д.) Часто можно использовать для сокращения кода (и более запутанный).

4
ответ дан 1 December 2019 в 17:23
поделиться

Я бы предположил, что "секрет" заключается в предоставлении родных операций для часто повторяющихся задач.

В той области, для которой изначально был задуман perl, вам часто приходится

  • Принимать ввод по строкам
  • Вырезать пробелы
  • Разбивать строки на слова
  • Соединять пары данных
  • ...

и perl предоставляет простые операторы для выполнения этих задач. Короткие имена переменных и использование значений по умолчанию для многих вещей - это просто подливка.

Также perl не был первым языком, который пошел по этому пути. Многие возможности perl были украдены в более или менее целостном виде (или часто слегка улучшены) из sed и awk и различных оболочек. Молодец Ларри.

Конечно, perl не был последним, кто пошел по этому пути, вы найдете похожие возможности в python, php, ruby и .... Людям нравились результаты, и они не собирались отказываться от них только для того, чтобы получить более регулярный синтаксис.

1
ответ дан 1 December 2019 в 17:23
поделиться

Большинство людей не понимают смысла большей части синтаксиса Perl и операторов по умолчанию. Perl в значительной степени является языком "DWIM" (делай то, что я имею в виду). Одна из основных целей его разработки - "сделать обычные вещи простыми, а трудные - возможными".

В рамках этой цели разработчики Perl говорят о кодировании синтаксиса по Хаффману и думают о том, что людям нужно делать, вместо того, чтобы просто давать им низкоуровневые примитивы. То, что вы делаете часто, должно занимать наименьшее количество символов, а функции должны вести себя как наиболее распространенное поведение. Это позволяет сэкономить довольно много работы.

Например, split имеет много значений по умолчанию, потому что есть некоторые случаи использования, когда оставление чего-либо без аргументов используется как обычный случай. Без аргументов, split разбивает $_ на пробельные символы, потому что это очень распространенное использование.

 my @bits = split;

Чуть менее распространенный, но все же частый случай - разбить $_ на что-то еще, поэтому есть немного более длинная версия этого:

 my @bits = split /:/;

И, если вы хотели явно указать источник данных, вы можете указать и переменную:

 my @bits = split /:/, $line;

Думайте об этом, как вы обычно поступаете в жизни. Если у вас есть обычная задача, которую вы часто выполняете, например, разговор с барменом, у вас есть сокращение для нее, которое охватывает обычный случай:

Обычный

Если вам нужно сделать что-то, немного отличающееся, вы немного расширяете это:

Обычный, но с луком

Но вы всегда можете отметить специфику

Грязный мартини Bombay Sapphire, взболтанный, а не перемешанный

Подумайте об этом в следующий раз, когда будете просматривать веб-сайт. Сколько кликов вам нужно, чтобы выполнить обычные действия? Почему одни сайты просты в использовании, а другие - нет? Чаще всего хорошие сайты требуют от вас минимум усилий для выполнения обычных действий. В отличие от моего банка, который требует не менее 13 щелчков мыши для оплаты счета по кредитной карте. Это должно быть очень просто - дать им денег. :)

.
10
ответ дан 1 December 2019 в 17:23
поделиться

Есть ряд факторов, которые делают Perl хорошим для игры в код:

  • Отсутствие типизации данных. Значения могут использоваться как строки и числа.
  • "Диагональный" синтаксис. Обычно называется TMTOWTDI (есть более одного способа сделать это.)
  • Переменные по умолчанию. Большинство функций действуют по $_, если не указан аргумент. (Некоторые действуют на @_.)
  • Функции, принимающие несколько аргументов (например, split), часто имеют значения по умолчанию, которые позволяют опустить некоторые аргументы или даже все.
  • "Волшебный" оператор readline, <>.
  • Функции более высокого порядка, такие как map и grep
  • Регулярные выражения интегрированы в синтаксис (т.е. не являются отдельной библиотекой)
  • Операторы короткого замыкания возвращают последнее проверенное значение.
  • Операторы замыкания могут быть использованы для управления потоком.

Кроме того, без строгих операторов (которые по умолчанию выключены):

  • Вам не нужно объявлять переменные.
  • Неразборчивые слова автоцитируются в строки.
  • undef становится либо 0, либо '' в зависимости от контекста.

Теперь, когда с этим покончено, позвольте мне прояснить один момент:

Гольф - это игра.

Здорово стремиться к тому уровню perl-фу, который позволяет вам быть хорошим игроком, но во имя $DIETY не играйте в гольф реальным кодом. Во-первых, это ужасная трата времени. Вы можете потратить час на то, чтобы убрать несколько символов. Гофрированный код хрупок: он почти всегда делает серьезные допущения и легкомысленно игнорирует проверку ошибок. Настоящий код не может позволить себе быть таким небрежным. Наконец, вашей целью как программиста должно быть написание ясного, надежного и удобного в обслуживании кода. В программировании есть поговорка: Всегда пишите свой код так, как будто человек, который будет его сопровождать, - жестокий социопат, который знает, где вы живете.

Так что, во что бы то ни стало, начинайте играть в гольф; но осознавайте, что это всего лишь игра, и относитесь к этому как к таковой.

32
ответ дан 1 December 2019 в 17:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: