Как сохранить подменю regex (search/replace) в переменной, аналогичной qr//
Я пытаюсь сохранить регулярное выражение 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
.
Ответы
Ответ 1
Вы должны хранить 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";
Ответ 2
Как вы уже выяснили, нет способа прямого хранения регулярного выражения подстановки, например, регулярное выражение соответствия (с 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 ...;