|
In Part 1 we discussed the //o modifier, which compiles a regexp just once. This
suggests that a compiled regexp is some data structure that can be stored once and used again
and again. The regexp quote qr// does exactly that: qr/string/
compiles the string as a regexp and transforms the result into a form that can be
assigned to a variable:
$reg = qr/foo+bar?/; # reg contains a compiled regexp
|
|
Then $reg can be used as a regexp:
$x = "fooooba";
$x =~ $reg; # matches, just like /foo+bar?/
$x =~ /$reg/; # same thing, alternate form
|
|
$reg can also be interpolated into a larger regexp:
$x =~ /(abc)?$reg/; # still matches
|
|
As with the matching operator, the regexp quote can use different delimiters, e.g., qr!!,
qr{} and qr~~. The single quote delimiters qr'' prevent
any interpolation from taking place.
Pre-compiled regexps are useful for creating dynamic matches that don't need to be recompiled
each time they are encountered. Using pre-compiled regexps, simple_grep program can
be expanded into a program that matches multiple patterns:
% cat > multi_grep
#!/usr/bin/perl
# multi_grep - match any of <number> regexps
# usage: multi_grep <number> regexp1 regexp2 ... file1 file2 ...
$number = shift;
$regexp[$_] = shift foreach (0..$number-1);
@compiled = map qr/$_/, @regexp;
while ($line = <>) {
foreach $pattern (@compiled) {
if ($line =~ /$pattern/) {
print $line;
last; # we matched, so move onto the next line
}
}
}
^D
% multi_grep 2 last for multi_grep
$regexp[$_] = shift foreach (0..$number-1);
foreach $pattern (@compiled) {
last;
|
|
Storing pre-compiled regexps in an array @compiled allows us to simply loop
through the regexps without any recompilation, thus gaining flexibility without sacrificing
speed.
|
|