Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^2: qr// and user provided regex patterns...

by misterMatt (Novice)
on Aug 02, 2009 at 07:33 UTC ( #785205=note: print w/ replies, xml ) Need Help??


in reply to Re: qr// and user provided regex patterns...
in thread qr// and user provided regex patterns...

Okay, I've managed to get this to work perfectly with a regular match (//) - but when I try to do a substitution(s///), the pattern fails to match anything - and no substitution is done. I'm calling the program like this: -r "s/matt/matthew/" -i -g, with the text 'matt, Matt'. Here is the code that processes the substitution bit:

if($options{r}){ #variable grab, add flags to pattern if they exist. my $pattern = $options{r}; $pattern .= 'g' if $options{g}; $pattern .= 'i' if $options{i}; $pattern .= 's' if $options{s}; #compile that stuff with eval my $compd_pattern = eval "qr($pattern)" or die $@; print "Please enter the text you wish to run the pattern on: "; my $text = <STDIN>; chomp $text; #do work and display if($text =~ $compd_pattern){ print $text; } else{ print "$pattern on \n\t{$text} Failed. "; } } #end R FLAG


Comment on Re^2: qr// and user provided regex patterns...
Download Code
Re^3: qr// and user provided regex patterns...
by toolic (Chancellor) on Aug 02, 2009 at 13:51 UTC
    I suspect that qr was not intended to be used on an entire subsitution operator like that. I believe it should only be used on the regular expression portion (left side) of the subsitution. See perlop.

    Here is an example script which uses s/// as a command-line option:
    http://www.cpan.org/authors/id/F/FO/FORMAN/ren-regexp-1.5

      so I pretty much will have to split it and evaluate it like this: eval("$text =~ s/$pa/$tx/$md"); It might be difficult splitting a regex that could contain multiple /'s. I'll have to adjust the program so the user enters the pattern, and replacement separately I guess.
Re^3: qr// and user provided regex patterns...
by JadeNB (Chaplain) on Aug 03, 2009 at 15:46 UTC
    As toolic points out, qr// is meant to quote a pattern, not an entire substitution. If you want to pass in literal substitutions, rather than just patterns, then just eval at a different point:
    eval "\$text =~ $pattern";

    By the way, ikegami suggested using (?i:) in place of a string-based eval. Since such evals are always a cause for concern, and should be a cause for terror when run on user-provided input, are you sure that you considered the alternative properly before making your decision?

    If you're not happy with the inability of a (?i:)-type solution to handle substitutions, then you can probably just offer --search and --replace --by flags so that the user can specify directly what he or she wants.

Re^3: qr// and user provided regex patterns...
by ikegami (Pope) on Aug 04, 2009 at 03:24 UTC
    • It makes no sense to let the user specify /g for a match. You can't even use it on qr// because it makes no sense. ixsm are the four modifiers that apply to the pattern as opposed to the operator.

    • The followign doesn't make much sense:

      my $compd_pattern = eval "qr($pattern)" or die $@;

      It removes the ability of qr// to quote, which is what you want. The code should be

      my $compd_pattern = qr($pattern);
    • You say you have problems doing substitutions, but you didn't show us your attempt (despite your claim). You should have no problems using a qr// pattern in a substitution.

    my $pat = ...; my $repl = ...; my $mods = ''; $mods .= 'i' if ...; $mods .= 's' if ...; $mods .= 'm' if ...; $mods .= 'x' if ...; my $re = qr/(?$mods:$pat)/; if (...) { s/$re/$repl/g; } else { s/$re/$repl/; }
      You say you have problems doing substitutions, but you didn't show us your attempt (despite your claim). You should have no problems using a qr// pattern in a substitution.
      I think that misterMatt's problem was that he was trying to stuff a substitution into a qr//, like:
      my $substitution = 's/out/in/'; my $pattern = qr/$substitution/;
      which, naturally, doesn't work (well, doesn't cause a substitution, anyway).

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://785205]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2014-09-21 12:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (168 votes), past polls