Take the 2-minute tour ×

I'm trying to make an on-the-fly pattern tester in Perl. Basically it asks you to enter the pattern, and then gives you a >>>> prompt where you enter possible matches. If it matches it says "%%%% before matched part after match" and if not it says "%%%! string that didn't match". It's trivial to do like this:

    } else {

but I want to be able to enter the pattern like /sometext/i rather than just sometext I think I'd use an eval block for this? How would I do such a thing?

share|improve this question
Perhaps you should just use Devel::REPL instead of writing your own. –  jrockway Jul 10 '09 at 22:48
it's to learn Perl, not for a project –  Carson Myers Jul 10 '09 at 22:53
I'm confused: for the purpose of the exercise, why can't you simply use /$pattern/i? Having said that, don't forget that you can always attack the problem the other way: change the string you're testing (make it all upper or all lower) rather than changing the match. This is often useful when handling simple user-input (to catch typos): Q or q, QuiT, quIt, etc. –  Telemachus Jul 10 '09 at 23:38
I was building off of the exercise I had--it's not that I wanted it to match any case all the time, but I wanted to be able to specify the whole regex from input. It was my own exercise –  Carson Myers Jul 11 '09 at 4:07
add comment

3 Answers

up vote 1 down vote accepted

This sounds like a job for string eval, just remember not to eval untrusted strings.


use strict;
use warnings;

my $regex = <>;
$regex = eval "qr$regex" or die $@;
while (<>) {
    print  /$regex/ ? "matched" : "didn't match", "\n";

Here is an example run:

perl x.pl
didn't match
share|improve this answer
How would this work with a substitution instead of a match? –  misterMatt Jul 31 '09 at 19:43
You mean if the user passes in the string "s/foo/bar/"? In that case I would say something like my $subst = <>; while (<>) { eval $subst or die $@; print }, but again, this is very dangerous. Whatever the user passes in on the first line will be executed as Perl code. –  Chas. Owens Jul 31 '09 at 20:24
I did try something similar - but the patter in the substitution kept failing to match anything. –  misterMatt Aug 1 '09 at 5:20
add comment

You can write /(?i:<pattern>)/ instead of /<pattern>/i.

share|improve this answer
add comment

This works for me:

my $foo = "My bonnie lies over the ocean";

print "Enter a pattern:\n";
while (<STDIN>) {
   my $pattern = $_;
   if (not ($pattern =~ /^\/.*\/[a-z]?$/)) {
      print "Invalid pattern\n";
   } else {
      my $x = eval "if (\$foo =~ $pattern) { return 1; } else { return 0; }";
      if ($x == 1) {
         print "Pattern match\n";
      } else {
         print "Not a pattern match\n";
   print "Enter a pattern:\n"
share|improve this answer
add comment

Your Answer


