Perl: как получить оригинальное регулярное выражение из предварительно скомпилированной версии? - PullRequest
11 голосов
/ 30 ноября 2011

Простой код:

use 5.014;
use warnings;

my $re = <DATA>;
chomp $re;
my $re2 = qr/$re/;
say $re2;
__END__
^\w$

Результат:

(?^u:^\w$)      #added the (?^u:

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

Мотивация: регулярное выражениеявляется значением конфигурации, поэтому необходимо:

  • прочитать его
  • скомпилировать
  • сохранить его в файл для последующего использования.

Но не могу сохранить скомпилированное регулярное выражение для последующего использования, потому что при каждой компиляции регулярное выражение расширялось с помощью (? ^ U:, поэтому после нескольких циклов я заканчивал следующим образом:

(?^u:(?^u:(?^u:(?^u:(?^u:^\w$)))))

, поэтомувопрос:

  • есть ли здесь какой-нибудь правильный способ, как сохранить скомпилированную версию?
  • если нет способа - как декомпилировать, чтобы получить оригинальную версию?
  • есть идеи?

Ответы [ 4 ]

15 голосов
/ 30 ноября 2011

Хотя я просто сохранял бы строковую копию для использования данных, а затем компилировал копию, когда мне было необходимо ее использовать, вы также можете использовать функцию regexp_pattern из основного модуля re для возврата шаблон, использованный для создания скомпилированного регулярного выражения:

use re 'regexp_pattern';

print regexp_pattern qr/^\w$/;

отпечатков

^\w$
4 голосов
/ 30 ноября 2011

re::regexp_pattern

Кредиты впит за указание на MagNET # perl .

3 голосов
/ 01 декабря 2011

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

qr/foo/                  # pat: foo  flags: u
qr/foo/u                 # pat: foo  flags: u
use re '/u';  qr/foo/    # pat: foo  flags: u

qr/foo/a                 # pat: foo  flags: a
use re '/a';  qr/foo/    # pat: foo  flags: a

qr/foo/i                 # pat: foo  flags: ui
use re '/i';  qr/foo/    # pat: foo  flags: ui
use re '/a';  qr/foo/i   # pat: foo  flags: ai
use re '/ai'; qr/foo/    # pat: foo  flags: ai

Чтобы получить как можно ближе к исходному оператору, вы хотите

use re qw( regexp_pattern );
my ($pat, $flags) = regexp_pattern($re);
$pat =~ s{/}{\\/}g;
say qq{qr/$pat/$flags};
0 голосов
/ 30 ноября 2011

Возможно так же просто, как:

...
($reoriginal = $re2) =~ s{^\(\?.+:(.+)\)}{$1};
say $reoriginal
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...