Carson Myers
Carson Myers

Reputation: 38564

evaluating a user-defined regex from STDIN in Perl

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:

while(<>){
    chomp;
    if(/$pattern/){
        ...
    } 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?

Upvotes: 0

Views: 2770

Answers (3)

Chas. Owens
Chas. Owens

Reputation: 64939

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

#!/usr/bin/perl

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
/foo/i
foo
matched
Foo
matched
bar
didn't match
^C

Upvotes: 1

jrockway
jrockway

Reputation: 42684

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

Upvotes: 1

joshk0
joshk0

Reputation: 2614

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"
}

Upvotes: -1

Related Questions