Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Store regular expressions in a file.

by yoda54 (Monk)
on Nov 11, 2010 at 10:27 UTC ( #870806=perlquestion: print w/ replies, xml ) Need Help??
yoda54 has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I'd like to read a bunch of regular expressions from a flat text for use in a script. After I read the file, how do I tell Perl thats this 'data' is a regular expression?

I'd like to accomplish something like the following.

#!/usr/bin/perl use strict; use warnings; my $data = "duck"; while(<DATA>) { if ($data =~ $_) { print "$data\n"; } } __DATA__ s/duck/luck/qr

Comment on Store regular expressions in a file.
Download Code
Re: Store regular expressions in a file.
by BrowserUk (Pope) on Nov 11, 2010 at 10:46 UTC

    You could eval the code into existence. People decry it, but it is one thing that makes dynamic languages so powerful:

    #!/usr/bin/perl use strict; use warnings; my $data = "duck"; while(<DATA>) { chomp; my $code = eval "sub{ \$_[0] =~ $_ }" // die $@; if( $code->( $data ) ) { print "$data\n"; } } __DATA__ s/duck/luck/

    Produces:

    c:\test>junk02 luck

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Store regular expressions in a file.
by JavaFan (Canon) on Nov 11, 2010 at 10:48 UTC
    I'd like to read a bunch of regular expressions from a flat text for use in a script. After I read the file, how do I tell Perl thats this 'data' is a regular expression?
    Replace "regular expression" with "number", and ask yourself the same question. How does Perl do that?
Re: Store regular expressions in a file.
by cdarke (Prior) on Nov 11, 2010 at 10:58 UTC
    this 'data' is a regular expression

    No, it is not a regular expression, only the duck is a regular expression. s is a Perl operator. If you can it would be a lot easier to have two columns, the first being the RE pattern ('duck') and the second being the replacement text ('luck') and then read them into variables (using split) - it is perfectly valid (and common) to store an RE in a Perl variable.

    Otherwise you will be reduced to doing nasty things like eval, and you don't want to go there.
      So something like this? I don't get any output.

      Thanks

      #!/usr/bin/perl use strict; use warnings; my $data = "duck"; my $r; while(<DATA>) { chomp; my ($x, $y) = split(/\s/, $_); $r->{$x} = qr/$y/; if ($data =~ $r->{"duck"}) { print "$data\n"; } } __DATA__ duck s/duck/luck/
Re: Store regular expressions in a file.
by mjscott2702 (Pilgrim) on Nov 11, 2010 at 11:42 UTC
    If you just wanted to create regular expressions for matching from a file, you could use the qr quoting operator, but don't think that will work for substituting as you appear to want to do - as others have pointed out, you would probably have to use eval for that.
      I see.

      Thanks

        This also works:

        #!/usr/bin/perl use strict; use warnings; my $data = "duck"; while(<DATA>) { chomp; my( $find, $replace ) = split ' ', $_, 2; if( $data =~ s[\Q$find][$replace]e ) { print "$data\n"; } } __DATA__ duck luck

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Store regular expressions in a file.
by sundialsvc4 (Abbot) on Nov 11, 2010 at 12:08 UTC

    The magic voodoo you are looking for is:   qr/some_expression/.

    This operator compiles a regular expression that is made from some_string.

    When constructing the string, be careful:   you might be tempted to use interpolation (double-quotes...) but this will cause the “rabbit-food” of the regex syntax itself to be turned into escape-characters.

    Furthermore, you might find that you can successfully put a string-variable reference into the regular expression string (i.e. without using qr//), and find that it is properly interpolated.   If you simply want to substitute “a particular string to search for” into an otherwise-fixed expression, this is one way to do that.

    If the regexes to be used are truly arbitrary, however, you will want to use qr//, and to enclose that statement in an eval block to trap runtime errors caused by invalid regex syntax.

Re: Store regular expressions in a file.
by roboticus (Chancellor) on Nov 11, 2010 at 12:56 UTC

    yoda54:

    I put this together:

    #!/usr/bin/perl use strict; use warnings; # Read the regexes my @Rexes; while (my $t=<DATA>) { chomp $t; last if $t=~/^$/; my ($regex, $repl) = split /\t+/, $t; push @Rexes, [ qr($regex), $repl ]; } # Process the text while (my $l = <DATA>) { $l=~s/$$_[0]/$$_[1]/eg for @Rexes; print $l; } __DATA__ duck cluck a(b+)c c$1a That bird says "duck!" xyzzy plugh ac abc abbc abbbc

    It mostly works, but as you can see from the following run, I haven't been able to make back references work...

    roboticus@Boink:~ $ perl pm870806_dyn_regex.pl That bird says "cluck!" xyzzy plugh ac c$1a c$1a c$1a

    ...roboticus

      #!/usr/local/bin/perl use strict; use warnings; use String::Interpolate qw(safe_interpolate); # Read the regexes my @Rexes; while (my $t = <DATA>) { chomp $t; last if $t =~ /^$/; my ($regex, $repl) = split /\t+/, $t; push @Rexes, [ qr($regex), $repl ]; } # Process the text while (my $l = <DATA>) { $l=~ s/$$_[0]/safe_interpolate($$_[1])/eg for @Rexes; print $l, "\n"; } __DATA__ duck cluck a(b+)c \uc${1}\ua That bird says "duck!" xyzzy plugh ac abc abbc abbbc
      That bird says "cluck!" xyzzy plugh ac CbA CbbA CbbbA
        Thanks everyone for the enlightenment!!

        ++eff_i_g:

        Sweet! I played with it for a while before giving up on the capture groups. I'll have to be sure to keep this handy!

        ...roboticus

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (8)
As of 2015-07-05 10:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (61 votes), past polls