Регулярное выражение Perl для соответствия литералам регулярного выражения Perl - PullRequest
2 голосов
/ 03 августа 2011

Существует ли спецификация в форме регулярного выражения perl, которая будет соответствовать всем литералам регулярного выражения perl?

Если это не так, есть ли спецификация на каком-либо языке для всех литералов регулярных выражений perl?

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

Характеристики, которые соответствуют после интерполяции переменных, идеальны, но и раньше тоже хороши.

Контекст: я пишу в perl (на самом деле, используя Parse :: RecDescent) метаязык, который компилируется в perl, и хочу идентифицировать литералы регулярных выражений и передавать их в perl.

Ответы [ 2 ]

5 голосов
/ 03 августа 2011

Эти операторы могут содержать произвольный код Perl, и спецификации для этого нет.

Например, в

/$x{ EXPR }/

и

s// EXPR /e

EXPRможет быть практически любым допустимым выражением Perl.

Однако я не думаю, что вам действительно нужно знать, как его анализировать.Вам просто нужно знать, где это заканчивается.И это довольно просто.Perl также должен уметь это делать, прежде чем он сможет анализировать оператор, поэтому он запрещает определенные шаблоны кода.(Таким образом, «почти» выше.)

  • Любому вхождению разделителя должен предшествовать нечетное число «\».

  • В качестве исключения из вышеизложенного, когда разделитель равен (), [] или {}, разделители могут отображаться без экранирования, пока они сбалансированы.

balanced_paren_guts  : ( /(?:[^\\\(\)]|\\.)+/ | '(' balanced_paren_guts  ')' )(s?)
balanced_square_guts : ( /(?:[^\\\[\]]|\\.)+/ | '[' balanced_square_guts ']' )(s?)
balanced_curly_guts  : ( /(?:[^\\\{\}]|\\.)+/ | '{' balanced_curly_guts  '}' )(s?)


match_op        : <skip:> 'm' /\s*/ match_op_1 match_modifiers

match_op_1      : '(' <commit> balanced_paren  ')'
                | '[' <commit> balanced_square ']'
                | '{' <commit> balanced_curly  '}'
                | /(?x: ([^\\]) (?:(?!\1).|\\.)* \1 )/

match_modifiers : /\w+/


subst_op        : <skip:> 's' /\s*/ subst_op_1 subst_modifiers

subst_op_1      : '(' <commit> balanced_paren  ')' \s* subst_op_2
                | '[' <commit> balanced_square ']' \s* subst_op_2
                | '{' <commit> balanced_curly  '}' \s* subst_op_2
                | /(?x: ([^\\]) (?:(?!\1).|\\.)* \1 (?:(?!\1).|\\.)* \1 )/

subst_op_2      : '(' <commit> balanced_paren  ')'
                | '[' <commit> balanced_square ']'
                | '{' <commit> balanced_curly  '}'
                | /(?x: ([^\\]) (?:(?!\1).|\\.)* \1 )/

subst_modifiers : /\w+/

Примечания:

  • Правила могут некорректно обрабатывать "'" как разделитель.
  • Необходимо добавить правило, чтобы разрешить "\ "как разделитель, но я не думаю, что вы должны это поддерживать.
2 голосов
/ 03 августа 2011

Возможно, вы захотите взглянуть на исходный код YAPE :: Regex , который используется для анализа регулярных выражений Perl. Один большой недостаток заключается в том, что он не обновлялся с версии perl 5.6, что означает, что он не понимает никакого синтаксиса регулярных выражений, введенного с тех пор (особенно 5.10).

См. Также perlreref

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