Passing Multiple Parameters into a Tag Modifier
One advanced capability that is utilized by the regex_replace
modifier is the ability to pass multiple arguments into the modifier directly.
The regex_replace
modifier requires two parameters from the user: a) the pattern to search for, and b) the string to replace matches with. For example, the following example will replace all occurrences of the word “cat” with “dog” within the entry’s body:
<mt:EntryBody regex_replace="/cat/g","dog">
This is equivalent to the the regular expression:
s/cat/dog/g
Suppose you wanted to augment regex_replace
to take an optional third parameter which would indicate whether the pattern should be evaluated in a case insensitive manner. The modifier’s handler would then look like this:
sub _fltr_regexreplace {
my ($str, $val, $ctx) = @;
# This one requires an array
return $str unless ref($val) eq 'ARRAY';
my $patt = $val->[0];
my $replace = $val->[1];
my $options = $val->[2] ? "i" : "";
if ($patt =~ m!^(/)(.+)\1([A-Za-z]+)?$!${options}) {
$patt = $2;
my $global;
if (my $opt = $3) {
$global = 1 if $opt =~ m/g/;
$opt =~ s/[ge]+//g;
$patt = "(?$opt)" . $patt;
}
my $re = eval { qr/$patt/ };
if (defined $re) {
$replace =~ s!\\(\d+)!\$1!g; # for php, \1 is how you write $1
$replace =~ s!/!\/!g;
eval '$str =~ s/$re/' . $replace . '/' . ($global ? 'g' : '');
if ($@) {
return $ctx->error("Invalid regular expression: $@");
}
}
}
return $str;
}
Wow, that is some super serious perl code. Let’s focus on just the parts that are relevant to passing arguments:
1 sub _fltr_regex_replace {
2 my ($str, $val, $ctx) = @_;
3 # This one requires an array
4 return $str unless ref($val) eq 'ARRAY';
5 my $patt = $val->[0];
6 my $replace = $val->[1];
7 my $options = $val->[2] ? "i" : "";
Line 4 is useful because it tests to see if $val
is an array or not. If it is not then it aborts the regular expression and returns the value of $str
unmodified.
Line 5, 6 and 7 show how you reference the first, second and third arguments passed into the modifier respectively.