http://www.perlmonks.org?node_id=694387

This is something I made up for a quick tester of regexes against strings; since it remembers both, either one can be 'adjusted' as necessary. It shows not only whether the match succeeds but also anything that was captured by the memory parens. It works with stand-alone regexes, substitution expressions, and the 'tr' operator. It's not perfect - it's probably somewhat fragile - but it's worked well for me for several months now, happily parsing my regexes by the dozen. I hope others find it useful.
#!/usr/bin/perl -w # Created by Ben Okopnik on Mon Mar 24 23:35:26 EDT 2008 # Regex Explorer use strict qw/vars/; use Term::ReadLine; my $term = new Term::ReadLine 'Regex Explorer'; my $OUT = $term -> OUT || \*STDOUT; print $OUT "Exit by entering an empty string at any prompt.\n\n"; { my $string = $term->readline("String: "); exit if $string =~ /^$/i; my $regex = $term->readline("Regex: "); exit if $regex =~ /^$/i; if ($regex !~ /^\s*((?:y|tr|s|m)\W|\/)/){ print $OUT "The regex must be a valid match or a substitute ex +pression.\n\n"; redo; } my $tr = $regex =~ /^\s*(?:y|tr)\W/ ? 1 : 0; my $cap = $regex =~ /\([^?]/ ? 1 : 0; # This eval should fail on anything except a match, subst, or tr my $old_string = $string; eval "\$string =~ $regex"; if ($@){ print $OUT "$@\n\n"; redo; } # Restore original after this eval $string = $old_string; # Variables declared in the eval must be escaped; those that aren' +t # will be interpreted in the scope of the surrounding script. my $ret = eval qq% my \$match = \$string =~ $regex; my \$out = 'Matched: ' . (\$match ? "Yes" : "No"); if (\@+ > 1 && ! $tr && $cap){ \$out .= "\nCaptures:"; \$out .= qq" [#\$_: '" . (\${\$_} || '') . "']" for 1 .. \ +$#+; } return "\$out\n"; %; # End of eval print $OUT $@ ? "\nERROR: $@\n" : "\nResult: $string\n$ret\n"; redo; }

Replies are listed 'Best First'.
Re: Regex tester
by ww (Archbishop) on Jun 27, 2008 at 20:46 UTC
    ++ for effort, oko1, but you may wish to consider a couple small points:

    For example:

    String: now is the time Regex: /\stime/ Result: now is the time Matched: Yes

    might be uninformative to the newcomer who hasn't yet groked much about regexen (and, specifically, about the need to use capturing parens in your program to obtain appropriate feedback). OTOH, of course, it works splendidly for this (in which our presumed newcomer has come to understand captures, even if s/he can't follow your code):

    String: now time Regex: /now\s(time)/ Result: now time Matched: Yes Captures: [#1: 'time']

    So, Good to go! for those who have at least some of the basics... but:

    My bad! See alexm's correction, below.
    String: fred same joe time
    Regex: ?time?
    The regex must be a valid match or a substitute expression.

    String: |time|
    Regex: |time|
    The regex must be a valid match or a substitute expression.

    String: fred same time
    Regex: ~time~
    The regex must be a valid match or a substitute expression.

    String: fred same time
    Regex: !time!
    The regex must be a valid match or a substitute expression.

    Perhaps a brief addition to the use_instruction (line 10) specifying the use of /.../ as the acceptable regex delimiter for input to this script (or re-coding to accept the usual alternatives?) and a bit of clarification about the output would make your script an even more valuable tool.

      Regex: ?time? ... Regex: |time| ... Regex: ~time~ ... Regex: !time!

      You must add the m prefix unless you use the slash; it works the same way it does on Perl:

      String: fred same joe time Regex: m?time? Result: fred same joe time Matched: Yes String: fred same joe time Regex: m~time~ Result: fred same joe time Matched: Yes String: fred same joe time Regex: m|time| Result: fred same joe time Matched: Yes String: fred same joe time Regex: m!time! Result: fred same joe time Matched: Yes
Re: Regex tester
by koolgirl (Hermit) on Aug 24, 2008 at 05:19 UTC
    Wow, very nice. I'm going to play around with that one for a bit. I just started learning regex's in depth, so this is a great tool. I have one I constructed as well, which might be useful, if just a simple match test is your aim:
    #!usr/bin/perl $my_string = ""; $my_regx = ""; # This program tests regular expressions against a match. if ($my_string =~ /$my_regx/x) print "Matched: " . "\"" . $& . "\"" . "\n"; # print matc +h print "Before match: " . "\"" . $` . "\"" . "\n"; # print data + before match print "After match: " . "\"" . $' . "\"" . "\n"; # print data + after match }else { # do nothing } # end if print "Rockstar Programming Inc. All Rights Reserved\n";
    So, now I have yours to explore with and maybe my much simpler "matcher" could possibly be of use to you :)

      There are a few things here that could use a little tidying. First off, the mandatory mantra: Always use strictures (use strict; use warnings; - see The strictures, according to Seuss).

      Of more immediate benefit: if you find you need to include double quote character in a string use qq for quoting instead of " (see perlop's Quote and Quote-like Operators). For example your print statements become:

      print qq{Matched: "$&"\n}; # print match print qq~Before match: "$`"\n~; # print data before match print qq|After match: "$'"\n|; # print data after match

      although you may wish to use a here-doc instead (look for here-doc in the same docs mentioned above):

      print <<STUFF; Matched: "$&" Before match: "$`" After match: "$'" STUFF

      Perl reduces RSI - it saves typing
Re: Regex tester
by ambrus (Abbot) on Jun 29, 2008 at 09:30 UTC