Testing for a Valid Pattern
Problem
You want to let users enter their own patterns, but an invalid one would abort your program the first time you tried to use it.
Solution
Test the pattern in an eval
{}
construct first, matching against some dummy string. If
$@
is not set, no exception occurred, so you know
the pattern successfully compiled as a valid regular expression. Here
is a loop that continues prompting until the user supplies a valid
pattern:
do { print "Pattern? "; chomp($pat = <>); eval { "" =~ /$pat/ }; warn "INVALID PATTERN $@" if $@; } while $@;
Here’s a standalone subroutine that verifies whether a pattern is valid.
sub is_valid_pattern { my $pat = shift; return eval { "" =~ /$pat/; 1 } || 0; }
That one relies upon the block returning 1
if it
completes, which in the case of an exception, never happens.
Discussion
There’s no end to patterns that won’t compile. The user
could mistakenly enter "<I\s*[^>"
,
"*** GET RICH ***"
, or "+5-i"
.
If you blindly use the proffered pattern in your program, it will
cause an exception, normally a fatal event.
The tiny program in Example 6.9 demonstrates this.
Example 6-9. paragrep
#!/usr/bin/perl # paragrep - trivial paragraph grepper die "usage: $0 pat [files]\n" unless @ARGV; $/ = ''; $pat = shift; eval { "" =~ /$pat/; 1 } or die "$0: Bad pattern $pat: $@\n"; while (<>) { print "$ARGV $.: $_" if /$pat/o; }
That /o
is a promise to Perl that the interpolated variable’s contents are constant over the program’s entire run. It’s an efficiency ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.