You want to match something fuzzily.
Any time you want to be forgiving of misspellings in user input, you want to do fuzzy matching.
Use the String::Approx module, available from CPAN:
use String::Approx qw(amatch); if (amatch("PATTERN", @list)) { # matched } @matches = amatch("PATTERN", @list);
String::Approx calculates the difference between the pattern and each string in the list. If less than a certain number (by default, 10 percent of the length of the pattern) one-character insertions, deletions, or substitutions are required to make the string from the pattern, the string "matches" the pattern. In scalar context,
amatch
returns the number of successful matches. In list context, it returns those strings that matched.
use String::Approx qw(amatch); open(DICT, "/usr/dict/words") or die "Can't open dict: $!"; while(<DICT>) { print if amatch("balast"); }
ballast
balustrade
blast
blastula
sandblast
You can also pass options to
amatch
to control case-insensitivity and the number of insertions, deletions, or substitutions to have. These options are passed in as a list reference; they're fully described in the String::Approx documentation.
It must be noted that using the module's matching function seems to run between 10 and 40 times slower than Perl's built-in matching function. Only use String::Approx if you're after fuzziness in your matching that Perl's regular expressions can't provide.
The documentation for the CPAN module String::Approx; Recipe 1.16
6.12. Honoring Locale Settings in Regular Expressions | 6.14. Matching from Where the Last Pattern Left Off |