Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Executing a "/foo/flags" regex from a string

by Radiola (Monk)
on Dec 30, 2015 at 01:22 UTC ( [id://1151414]=perlquestion: print w/replies, xml ) Need Help??

Radiola has asked for the wisdom of the Perl Monks concerning the following question:

I wish to take a string like "/regex/i" (say, from the command line) and make a regex object with qr that I can execute just like I'd written that in the program text. I'm not sure about the best way to do it. I tried:

if ($search_term =~ m[^/.*/\w*$]) { # if it is in the form "/foo/x" or whatever, treat it as # though it had been specified in Perl program text $search_re = qr($search_term); }

If I input /tree/i, it returns a regex (?^:/tree/i) that searches for "/tree/i", which isn't what I want. I want something like (?^i:tree) which will match "tree" or "Tree" or "Street". That I can get using a string eval():

$search_re = eval("qr${search_term}");

Is there a better way to do this? This is a personal command-line tool, so I'm not really worried about malicious input to the string eval; but if there's a better way I'd like to know for the future.

Thanks,
Aaron

Replies are listed 'Best First'.
Re: Executing a "/foo/flags" regex from a string
by Rhandom (Curate) on Dec 30, 2015 at 01:59 UTC
    Here is a small snippet that should do what you were asking for (more or less):

    perl -E 'my $str = "/regex/i"; my ($pat, $flags) = $str =~ m{^/(.+)/([imsx]*)\z} ? ($1, $2) : die "Bad regex"; my $qr = qr/(?$flags:$pat)/; say qq{Matched "$_" with $qr} for grep {$_ =~ $qr} qw(foo bar baz reGex)' Matched "reGex" with (?^u:(?i:regex))


    my @a=qw(random brilliant braindead); print $a[rand(@a)];

      Ah, OK. I guess there's nothing more to the syntax of /regex/flags than, uh, the regex and the flags, so you don't risk losing anything by parcelling them out and putting them back together like that.

      Thanks!

      - Aaron

Re: Executing a "/foo/flags" regex from a string (qr flags)
by Anonymous Monk on Dec 30, 2015 at 01:52 UTC

    qr can do it as perlre syntax allows (?i) the same as /i

    $ perl -le " print int q{shoes} =~ /SHOES/ " 0 $ perl -le " print int q{shoes} =~ /SHOES/i " 1 $ perl -le " print int q{shoes} =~ /(?i)SHOES/ " 1

    App::Ack uses this trick

    You can use eval { no re qw/eval/; qr/$regex/ }; to see if the regex compiles

    See also Text::Glob#glob_to_regex

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1151414]
Front-paged by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-04-23 10:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found