Почему регулярные выражения не могут использовать ключевые слова вместо символов?

StackOverflow https://stackoverflow.com/questions/629573

  •  08-07-2019
  •  | 
  •  

Вопрос

Ладно, я едва разбираюсь в основах регулярных выражений, но почему они не могли спроектировать его так, чтобы использовать ключевые слова (например, SQL) вместо каких-то загадочных подстановочных знаков и условных обозначений?

Это для повышения производительности, поскольку регулярное выражение интерпретируется / анализируется во время выполнения?(не скомпилирован)

Или, может быть, для скорости написания?Учитывая, что когда вы выучите несколько "простых" комбинаций символов, вам станет проще ввести 1 символ вместо ключевого слова?

Это было полезно?

Решение

Вы действительно хотите это ?

Pattern findGamesPattern = Pattern.With.Literal(@"<div")
    .WhiteSpace.Repeat.ZeroOrMore
    .Literal(@"class=""game""").WhiteSpace.Repeat.ZeroOrMore.Literal(@"id=""")
    .NamedGroup("gameId", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal(@"-game""")
    .NamedGroup("content", Pattern.With.Anything.Repeat.Lazy.ZeroOrMore)
    .Literal(@"<!--gameStatus")
    .WhiteSpace.Repeat.ZeroOrMore.Literal("=").WhiteSpace.Repeat.ZeroOrMore
    .NamedGroup("gameState", Pattern.With.Digit.Repeat.OneOrMore)
    .Literal("-->");

Хорошо, но это ваши похороны , мужик.

Загрузите библиотеку, которая делает это здесь:
http://flimflan.com/blog/ReadableRegularExpressions.aspx

Другие советы

Регулярные выражения имеют математическую основу (фактически, теорию языка) и кодируются примерно так математическая формула.Вы можете определить их с помощью набора правил, например

  • каждый символ является регулярным выражением, представляющим самого себя
  • если a и b тогда это регулярные выражения a?, a|b и ab это тоже регулярные выражения
  • ...

Использование языка, основанного на ключевых словах, было бы большой нагрузкой для простых регулярных выражений.В большинстве случаев вы будете просто использовать простую текстовую строку в качестве шаблона поиска:

grep -R 'main' *.c

Или, может быть, очень простые шаблоны:

grep -c ':-[)(]' seidl.txt

Как только вы привыкнете к регулярным выражениям, этот синтаксис станет очень ясным и точным.В более сложных ситуациях вы, вероятно, будете использовать что-то другое, поскольку большое регулярное выражение, очевидно, трудно читать.

Perl 6 делает довольно революционный шаг вперед в удобочитаемости регулярных выражений. Рассмотрим адрес формы: 100 E Main St Springfield MA 01234

Вот умеренно читаемое регулярное выражение, совместимое с Perl 5, для его анализа (многие угловые случаи не обрабатываются):

 m/
     ([1-9]\d*)\s+
     ((?:N|S|E|W)\s+)?
     (\w+(?:\s+\w+)*)\s+
     (ave|ln|st|rd)\s+
     ([:alpha:]+(?:\s+[:alpha:]+)*)\s+
     ([A-Z]{2})\s+
     (\d{5}(?:-\d{4})?)
  /ix;

Это регулярное выражение Perl 6 имеет такое же поведение:

grammar USMailAddress {
     rule  TOP { <addr> <city> <state> <zip> }

     rule  addr { <[1..9]>\d* <direction>?
                  <streetname> <streettype> }
     token direction { N | S | E | W }
     token streetname { \w+ [ \s+ \w+ ]* }
     token streettype {:i ave | ln | rd | st }
     token city { <alpha> [ \s+ <alpha> ]* }
     token state { <[A..Z]>**{2} }
     token zip { \d**{5} [ - \d**{4} ]? }
  }

Грамматика Perl 6 - это класс, и все токены являются вызываемыми методами. Используйте это так:

if $addr ~~ m/^<USMailAddress::TOP>$/ {
     say "$<city>, $<state>";
}

Этот пример взят из сообщения, которое я представил на Мастерская Frozen Perl 2009 . Реализация Rakudo в Perl 6 достаточно завершена, чтобы этот пример работал сегодня.

Ну, если бы у вас были ключевые слова, как бы вы могли легко отличить их от фактически сопоставленного текста? Как бы вы справились с пробелами?

Исходный текст Компания: A Отдел .: B

Стандартное регулярное выражение:

Company:\s+(.+)\s+Dept.:\s+(.+)

Или даже:

Company: (.+) Dept. (.+)

Ключевое слово regex (изо всех сил стараюсь не получить мошенника ...)

"Company:" whitespace.oneplus group(any.oneplus) whitespace.oneplus "Dept.:" whitespace.oneplus group(any.oneplus)

Или упрощенно:

"Company:" space group(any.oneplus) space "Dept.:" space group(any.oneplus)

Нет, наверное, не лучше.

Потому что это соответствует теории формального языка и ее математическим обозначениям.

Это вина Перла ...!

На самом деле, точнее говоря, регулярные выражения пришли из ранней разработки Unix, и лаконичный синтаксис был тогда гораздо ценнее. Время хранения, обработки, физические терминалы и т. Д. Были очень ограничены, в отличие от сегодняшнего дня.

История регулярных выражений в Википедии объясняет больше.

Есть альтернативы Regex, но я не уверен, что кто-то действительно завоевал популярность.

РЕДАКТИРОВАТЬ: Исправлено Джоном Сондерсом: Регулярные выражения были популярны в Unix, но сначала были реализованы QED . Те же конструктивные ограничения применяются, тем более, к более ранним системам.

На самом деле нет, мир не начинался с Unix. Если вы прочитаете статью в Википедии, вы увидите, что

  

В 1950-х годах математик Стивен Коул Клин описал эти модели, используя свои математические обозначения, называемые регулярными множествами. Язык SNOBOL был ранней реализацией сопоставления с образцом, но не идентичен регулярным выражениям. Кен Томпсон встроил нотацию Клини в редактор QED как средство для сопоставления шаблонов в текстовых файлах. Позже он добавил эту возможность в редактор Unix, что в итоге привело к тому, что популярный поисковый инструмент grep использовал регулярные выражения

Это намного раньше, чем в PERL. Запись в Википедии о регулярных выражениях приписывает первые реализации регулярных выражений Кену Томпсону из UNIX Слава, кто реализовал их в QED, а затем в ed редактор. Я предполагаю, что команды имели короткие имена из соображений производительности, но гораздо раньше, чем на стороне клиента. Освоение регулярных выражений - это отличная книга о регулярных выражениях, которая предлагает возможность аннотировать регулярные выражения (с помощью / x флаг), чтобы было легче читать и понимать.

Потому что идея регулярных выражений, как и многих вещей, происходящих из UNIX, заключается в том, что они кратки, предпочитая краткость, а не читабельность. Это на самом деле хорошая вещь. Я закончил писать регулярные выражения (вопреки моему лучшему суждению) длиной 15 строк. Если бы у этого был подробный синтаксис, это не было бы регулярным выражением, это была бы программа.

На самом деле довольно легко реализовать " wordier " форму регулярного выражения - см. мой ответ здесь . В двух словах: напишите несколько функций, которые возвращают строки регулярных выражений (и при необходимости принимают параметры).

Я не думаю, что ключевые слова могут принести какую-либо пользу. Регулярные выражения как таковые являются сложными, но также очень мощными.

Что мне кажется более запутанным, так это то, что каждая поддерживающая библиотека изобретает свой собственный синтаксис вместо использования (или расширения) классического регулярного выражения Perl (например, \ 1, $ 1, {1}, ... для замен и многих других примеров) .

Я знаю, что он неправильно отвечает на ваш вопрос, но RegExBuddy имеет функцию, объясняющую ваше выражение на простом английском. Это может сделать его немного легче учиться.

Если используемый вами язык поддерживает регулярные выражения Posix , вы можете использовать их.

Пример:

\d

будет таким же, как

[:digit:]

Обозначение в скобках намного яснее относительно того, что оно соответствует. Я бы все равно выучил «!» Загадочные подстановочные знаки и символы, так как вы все равно будете видеть их в чужом коде и должны понимать их.

В таблице больше примеров на странице регулярных выражений.info .

По какой-то причине мой предыдущий ответ был удален.В любом случае, я думаю, что ruby regexp machine подошел бы по всем параметрам, по крайней мере http://www.rubyregexp.sf.net.Это мой собственный проект, но я думаю, что он должен сработать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top