дифференцирование и тестирование вариантов регулярных выражений - PullRequest
1 голос
/ 08 сентября 2011

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

Большинство этих различий включают семантику, связанную с тем, экранирован ли персонаж или нет. Это чаще всего проблема с круглыми скобками, но может применяться к фигурным скобкам и другим. Это, вероятно, является следствием синтаксиса языка или среды, в которой находится реализация. Например, если символ $ указывает имя переменной на каком-либо языке, можно ожидать, что регулярные выражения, представленные на этом языке, потребуют экранирования привязки «конец строки» для \$ или чего-то подобного. Но то, что сбивает с толку в этом пункте, - то, как Вы представляли бы фактический знак доллара. Я считаю, что Perl справляется с этим, заключая регулярное выражение в косые черты /.

Точно так же есть экранирование для определенных символов, например непечатаемых символов, таких как \n и \t. Кроме того, существуют похожие группы символов общего вида, такие как \d для цифр, \s для пробелов и \w, которые, как я только что узнал, охватывают подчеркивания и цифры. Я несколько раз пытался использовать \a для «алфавитной» группы, но это в итоге совпадало только с символом колокольчика 0x07.

Совершенно очевидно, что не существует простого и единственного решения, позволяющего узнать все различия в функциях и синтаксисе, предлагаемых множеством реализаций регулярных выражений, если не считать того, кто выполняет всю тяжелую работу и вносит результаты хорошо организованный стол. Здесь является одним из примеров именно этого, но, конечно, он не охватывает несколько программ, которые я сам интенсивно использую, в том числе vim, sed, Notepad ++, Eclipse, и считаю, что или не MS Word (по крайней мере, версия 2010, я подозреваю, что 2007 также имеет это, они называют это «подстановочными знаками») также имеет простую реализацию регулярных выражений.

Полагаю, я хочу быть настолько ленивым, насколько это возможно (в определенном смысле), пытаясь придумать способ определить для любой конкретной реализации регулярного выражения, что его «настройки выхода» вне всякого сомнения, применяя один ( или несколько) запросов.

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

Если никто не пытался создать такое чудовище, я мог бы выполнить эту задачу сам. Если это вообще возможно. Это возможно?

Я пытался придумать пример (это было просто, чтобы выяснить, является ли привязка EOL $ или \$), но в каждом случае мне приходилось использовать множество различных запросов поиска / замены, чтобы определить как программа будет реагировать на ввод.

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

Обновление: Ну, Notepad ++ не реализует оператор ИЛИ, обычно обозначаемый каналом |. Слово «подстановочные знаки» в Word также является плохой заменой, оно не имеет | или *. Я совершенно уверен, что отсутствие какого-либо из операторов регулярного выражения (union, concat, star) означает, что он не может генерировать регулярную грамматику, поэтому эти два исключены.

Я могу создать входной файл так:

$
*
]
EOL

и запрос

(\$)|(\*)|(\[)|($)

с заменой на

escDollar:\1:escStar:\2:escSQBrL:\3:Dollar:\4:

дает результат (при условии, что неэкранированные парены являются группами, а неэкранированные трубы - или)

escDollar:$:escStar::escSQBrL::Dollar::
escDollar::escStar:*:escSQBrL::Dollar::
]escDollar::escStar::escSQBrL::Dollar::
EOLescDollar::escStar::escSQBrL::Dollar::

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

Трудно увидеть, что происходит с якорем $, поскольку он соответствует нулевым символам, но не должно быть трудно найти решение для него. Кроме того, это не часто ошибочно. Больше всего меня волнуют труба, парен и разные скобки. Когда у вас есть 4 различных типа, есть 2 ^ 4 комбинации из экранированных и не экранированных версий, которые вы можете использовать. Метод проб и ошибок ужасен.

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

Казалось бы, для этого потребуется несколько запросов. Может быть возможно с хитро спроектированным перемешиванием обратной косой черты, паренов и каналов, чтобы выяснить комбинацию (всего 4 возможности в конце концов) с начальным запросом, а затем выбрать последующий запрос генератора матрицы на его основе.

Примерно так видно, что он может работать:

(e)
(f)

1064 * выполнение запроса *

\((f\))|\|\((e\))

заменить на

\1:\2

даст:

  • :(e, если сбежавшие парни - это группа, а сбежавшая труба - или
  • :e), если parens - группа, а сбежавшая труба - или
  • (f:, если сбежавшие парни - это группа, а труба - или
  • f):, если parens - группа, а pipe - или

Мне все еще не очень нравится это, потому что это требует второго запроса ко второму набору ввода. Слишком много настроек. Я могу просто сделать 4 копии «матричной» вещи.

1 Ответ

1 голос
/ 08 сентября 2011

В таблице на этой странице довольно хорошо обобщено, какие функции доступны в каких реализациях регулярных выражений:

http://www.regular -expressions.info / refflavors.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...