Matching Abbreviations
Problem
Suppose you had a list of commands, such as
"send"
, "abort"
,
"list"
, and "edit"
. The user
types one in, but you don’t want to make them type out the
whole thing.
Solution
You can use the following technique if the strings all start with
different characters or if you want to arrange the matches so one
takes precedence over another, as "SEND"
has
precedence over "STOP"
here:
chomp($answer = <>); if ("SEND" =~ /^\Q$answer/i) { print "Action is send\n" } elsif ("STOP" =~ /^\Q$answer/i) { print "Action is stop\n" } elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" } elsif ("LIST" =~ /^\Q$answer/i) { print "Action is list\n" } elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is edit\n" }
Or you can use the Text::Abbrev module:
use Text::Abbrev; $href = abbrev qw(send abort list edit); for (print "Action: "; <>; print "Action: ") { chomp; my $action = $href->{ lc($_) }; print "Action is $action\n"; }
Discussion
The first technique switches the typical order of a match. Normally
you have a variable on the left side of the match and a known pattern
on the right side. We might try to decide which action the user
wanted us to take by saying $answer
=~
/^ABORT/i
, which is true if
$answer
begins with the string
"ABORT"
. It matches whether
$answer
has anything after
"ABORT"
, so "ABORT
LATER"
would still match. Handling abbreviations
generally requires quite a bit of ugliness:
$answer
=~
/^A(B(O(R(T)?)?)?)?$/i
.
Compare the classic "variable
=~
pattern"
with ...
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.