Perhaps you might re-think your approach.
You want to pass in to a function a regex substitution, probably because the function will be deriving the text to be operated upon from some other source (reading from a file, socket, etc.). But you're conflating regular expression with regular expression substitution.
In the expression, s/foo/bar/
, you actually have a regular expression ("/foo/") and a substitution ("bar") that should replace what is matched by the expression. In the approaches you've tried thus far, you ran into problems trying to use eval
, mainly because of the likelihood of special characters in the expression that either interfere with eval
or get interpolated (i.e. gobbled up) in the process of evaluation.
So instead, try passing your routine two arguments: the expression and the substitution:
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...
}
This approach has an added benefit: if your regex pattern doesn't have any special characters in it, you can just pass it in directly:
apply_regex('foo', 'bar');
Or, if it does, you can use the qr//
quoting-operator to create a regex object and pass that as the first parameter:
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
Most of all, you really don't need eval
or the use of code-references/closures for this task. That will only add complexity that may make debugging harder than it needs to be.
Randy