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

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

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

А может, для скорости написания? Учитывая, что когда вы изучаете некоторые «простые» комбинации символов, становится легче набирать символ 1 вместо ключевого слова?

Ответы [ 14 ]

34 голосов
/ 10 марта 2009

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

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

10 голосов
/ 10 марта 2009

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

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

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

grep -R 'main' *.c

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

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

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

8 голосов
/ 15 марта 2009

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 достаточно завершена, чтобы этот пример работал сегодня.

7 голосов
/ 10 марта 2009

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

Исходный текст Компания: Отдел: 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)

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

5 голосов
/ 10 марта 2009

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

4 голосов
/ 10 марта 2009

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

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

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

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

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

3 голосов
/ 10 марта 2009

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

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

2 голосов
/ 10 марта 2009

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

1 голос
/ 01 июля 2011

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

1 голос
/ 15 марта 2009

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

Пример:

\d

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

[:digit:]

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

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

...