As far as fuzzy matching goes, I posted code once that showed how to do fuzzy matching with Perl regexes. Here's an updated version:
sub mk_fuzzy { our ($m, $i, $d) = splice @_, 0, 3; use re 'eval'; qr{ (?{ [ $i, $d, $m ] }) ^ @{[ map $_[$_] =~ /!$/ ? substr($_[$_],0,-1) : qq{ (?: $_[$_] (?: | (?(?{ \$^R->[0] }) @{[ $_ < $#_ and "(?! $_[$_+1] + )" ]} (?s: . ) (?{ [ \$^R->[0] - 1, \$^R->[1], \$^R->[2] ] }) | (?!) + ) ) | (?(?{ \$^R->[1] }) (?{ [ \$^R->[0], \$^R->[1] - 1, \$^R->[2] + ] }) | (?!) ) | (?(?{ \$^R->[2] }) (?! $_[$_] ) (?s: . ) (?{ [ \$^R->[0], \$ +^R->[1], \$^R->[2] - 1 ] }) | (?!) ) ) }, 0 .. $#_ ]} $ (?{ [ [$m-$^R->[2], $m], [$i-$^R->[0], $i], [$d-$^R->[1], $d] ] }) }x; }
The use of the function is as follows:
my $test = mk_fuzzy( 1, # max number of modifications to allow 1, # max number of insertions to allow 1, # max number of deletions to allow qw( p e r l ) ); for my $word (qw( pearl earl pearly peely )) { if ($word =~ $test) { print "$word is close enough to 'perl'\n"; } else { print "$word isn't enough like 'perl'\n"; } }
This reports that pearl, earl, and peely are close to "perl".

The reason I send the letters of the word individually is because the function allows you to follow a letter with a ! which means it MUST appear in the word. (And the 'letters' don't have to be just letters, they could be multi-character strings.) Example:

my $test = mk_fuzzy( 1, # max number of modifications to allow 1, # max number of insertions to allow 1, # max number of deletions to allow qw( p e r! l ) # must have the 'r' in this relative location ); for my $word (qw( pearl earl pearly peely )) { if ($word =~ $test) { print "$word is close enough to 'perl'\n"; } else { print "$word isn't enough like 'perl'\n"; } }
This one only reports pearl and earl, since peely didn't keep the 'r'.

After a successful match, by the way, you can inspect $^R to see how many modifications, insertions, and deletions were necessary:

if ($word =~ $test) { my ($m_used, $m_allowed) = @{ $^R->[0] }; my ($i_used, $i_allowed) = @{ $^R->[1] }; my ($d_used, $d_allowed) = @{ $^R->[2] }; print "Using $m_used mods, $i_used inserts, and $d_used dels, $word +matched\n"; }

Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

In reply to Re: Splitting strings into words when there are no separators by japhy
in thread Splitting strings into words when there are no separators by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.