Как сохранить регулярное выражение подстановки (поиск / замена) в переменной, аналогично qr // - PullRequest
10 голосов
/ 05 февраля 2011

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

Вот пример, который использует нормальное совпадение, чтобы показать, что я намерен делать.

my %file_structure = (
    header => qr/just another/,
    table  => qr/perl beginner/,
)

Теперь я могу вызвать это с помощью $line =~ $file_structure{'header'}, и он вернет undef, илиtrue, если шаблон соответствует.

Однако я бы хотел сказать $line =~ $file_structure{'foo'}, где $file_structure{'foo'} содержит что-то вроде s/beginner/hacker/g.

Ответы [ 2 ]

10 голосов
/ 05 февраля 2011

Вы должны хранить 2 части отдельно:

my %file_structure = (
    foo => {pat => qr/beginner/, repl => 'hacker'},
);

my $line = 'just another perl beginner';
$line =~ s/$file_structure{foo}{pat}/$file_structure{foo}{repl}/;
print "$line\n";

Что было бы намного безопаснее, чем прибегнуть к злому "eval EXPR":

my %file_structure = (
    foo => 's/beginner/hacker/',
);

my $line = 'just another perl beginner';
eval "\$line =~ $file_structure{foo}";
print "$line\n";
9 голосов
/ 05 февраля 2011

Как вы обнаружили, нет способа напрямую сохранить регулярное выражение подстановки, как вы можете сопоставить регулярное выражение (с qr//). Вы можете разбить части и рекомбинировать их, как показывает tadmc. Другой способ сделать это - сохранить подстановку в подпрограмме:

my %file_structure = (
   foo_uses_default => sub {s/foo/bar/},
   foo_takes_arg    => sub {$_[0] =~ s/foo/bar/},
   foo_does_either  => sub {(@_ ? $_[0] : $_) =~ s/foo/bar/},
);

$file_structure{foo_uses_default}() for ...;
$file_structure{foo_uses_arg}($_)   for ...;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...