Recipe 6.13. Approximate Matching
Author: Tom Christiansen & Nathan Torkington
Date: 1999-07-02T01:34:32Z

#

| Chapter 6 Pattern Matching |

## 6.13. Approximate Matching

### Problem

You want to match something fuzzily.

Any time you want to be forgiving of misspellings in user input, you want to do fuzzy matching.

### Solution

Use the String::Approx module, available from CPAN:

    use String::Approx qw(amatch);

    if (amatch("PATTERN", @list)) {
        # matched
    }

    @matches = amatch("PATTERN", @list);

### Discussion

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.

### See Also

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