Возможно, вы могли бы переосмыслить свой подход.
Вы хотите передать в функцию подстановку регулярных выражений, возможно, потому, что функция будет извлекать текст для обработки из какого-либо другого источника (чтение из файла, сокета и т. Д.). Но вы смешиваете регулярное выражение с заменой регулярного выражения .
В выражении s/foo/bar/
у вас есть регулярное выражение ("/ foo /") и подстановка ("bar"), которая должна заменить то, что соответствует выражению. В тех подходах, которые вы пробовали до сих пор, вы столкнулись с проблемами, пытаясь использовать eval
, главным образом из-за вероятности использования специальных символов в выражении, которые либо мешают работе eval
, либо интерполируются (т. Е. Поглощаются) в процессе. оценки.
Итак, вместо этого попробуйте передать вашей программе два аргумента: выражение и подстановку:
sub apply_regex {
my $regex = shift;
my $subst = shift || ''; # No subst string will mean matches are "deleted"
# some setup and processing happens...
# time to make use of the regex that was passed in:
while (defined($_ = <$some_filehandle>)) {
s/$regex/$subst/g; # You can decide if you want to use /g etc.
}
# rest of processing...
}
Этот подход имеет дополнительное преимущество: если в вашем шаблоне регулярных выражений нет специальных символов, вы можете просто передать его напрямую:
apply_regex('foo', 'bar');
Или, если это так, вы можете использовать оператор цитирования qr//
, чтобы создать объект регулярного выражения и передать его в качестве первого параметра:
apply_regex(qr{(foo|bar)}, 'baz');
apply_regex(qr/[ab]+/, '(one or more of "a" or "b")');
apply_regex(qr|\d+|); # Delete any sequences of digits
Более того, вам действительно не нужно eval
или использование кодовых ссылок / замыканий для этой задачи. Это только добавит сложности, которая может сделать отладку сложнее, чем нужно.
Randy