Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
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":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-04-19 10:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found