package RegexDebugger; require EXPORTER; @ISA = qw(Exporter); @EXPORT_OK = qw(traceMatch findLongestMatch); use strict; sub traceMatch { my ($string, $regex ) = @_; my $matchtrace = qr{ (?{print "Match at [$`<$&>$']\n"}) (?!) }x; $string =~ m{$regex$matchtrace}; } sub findLongestMatch { my ($string, $regex) = @_; my $longest = undef; my $recordpossiblematch = qr{ (?{ # Checks if this is the longest match if( not defined( $longest ) or length( $& ) > length( longest ) ){ $longest = $&; } }) (?!) # Force failure to find next 'match' }x; $string =~ m{$regex$recordpossiblematch}; return $longest; } 1; =head1 NAME RegexDebugger - Utility functions for debugging regular expressions =head1 SYNOPSIS Implementes two uses of embedded code in regular expressions as described in the Owl Book. Provides two functions, one that finds the longest match and another that prints all possible matches. $longest = &RegexDebugger::findLongestMatch( "oneselfsufficient", qr{one(self)?(sufficient)?} ); &RegexDebugger::traceMatch( "123", qr{\d+} ); =head1 DESCRIPTION Jeffrey Friedl's excellent "Mastering Regular Expressions" gives some neat examples of embebbed code constructs in perl regular expressions. As these examples were both useful and enlightening, I implemented them as an excercise. Putting them into a separate module seemed like the next logical step after abstracting the functionality of the examples into functions. =over =item findLongestMatch( STRING, EXPRESSION ) Applies the regular expression object given by B to B and returns the longest match. The example given in the Owl: my $longest = &RegexDebugger::findLongestMatch( "oneselfsufficient", qr{one(self)?(sufficient)?} ); print "Longest match found '$longest'.\n" if $longest; Results in: Longest match found 'oneselfsufficient'. =item traceMatch( STRING, EXPRESSION ) Applies the regular expression object given by B to B and prints out all possible matches. This will force a lot of backtracking, so complicated regexes on large strings may provoke a tea break. Again, we let the Owl do the talking: &RegexDebugger::traceMatch( "123", qr{\d+} ); Gives: Match at [<123>] Match at [<12>3] Match at [<1>23] Match at [1<23>] Match at [1<2>3] Match at [12<3>] =back =head1 AUTHOR Per Christian Nødtvedt =head1 CREDITS Maximum respect and gratitude to the author of the Owl, Jeffrey Friedl, who wrote the regular expressions used in this module. May his days be long and his nights productive.