Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Regular Expression Question

by Anonymous Monk
on Apr 03, 2003 at 18:03 UTC ( [id://247830]=perlquestion: print w/replies, xml ) Need Help??

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

How do you you use a variable in a regular expression and still use the format of regular expression? Such as:

$word = "cccv"; $pat = "[^aeiou][^aeiou][^aeiou][aeiou]"; if($word =~ /($pat)/{ $yep++; }
How do I get $pat to be treated as a normal reg expression?
The reason for this wierd idea, is that I have to match words in a dictonary in the form of c = consonat
and v = vowel. So, I have a user input something like 'ccvv' and I just subsitute the reg expression for each letter (i.e.  s/v/[aeiou]/g;)and want to use it in that way, but it doesn't want to work.
Thanks, P0werz

Replies are listed 'Best First'.
Re: Regular Expression Question
by kelan (Deacon) on Apr 03, 2003 at 18:18 UTC

    You're pretty close, but you aren't doing any substitution. You want something more like this:

    $pat = "cccv"; $pat =~ s/c/[^aeiou]/g; $pat =~ s/v/[aeiou]/g; if ($word =~ /($pat)/) { $yep++; }
    You need to actually substitute the 'c's and 'v's for the character classes before trying to do the matching.

    kelan


    Perl6 Grammar Student

Re: Regular Expression Question
by dragonchild (Archbishop) on Apr 03, 2003 at 18:17 UTC
    my %regexen = ( v => qr/[aeiou]/i; c => qr/[a-z^aeiou]/i; ); # This is inputted somehow. my $pattern = 'cccv'; my $regex = join '', map { $regexen{$_} } split //, $pattern; # Get @dictionary somehow. foreach my $word (@dictionary) { print "$word matches" if $word =~ /$pattern/; }
    Note - this code is very untested.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      Just out of curiosity, when you join pre-compiled regexen as dragonchild did above, and stick the result into a variable, is the variable now treated like a pre-complied regex, or will it need to be recompiled again each time during the foreach loop?

Re: Regular Expression Question
by perlguy (Deacon) on Apr 03, 2003 at 20:41 UTC

    Once you've got your regex that you will be using to determine if a vowel/consonant combo is valid in your dictionary file, I would either pre-compile it using:

    my $regex = qr/$string/; while (my $word = <DICT>) { chomp($word); if ($word =~ $regex) { $yep++; } }

    or use the /o modifier (which assures the compiler that you won't be changing the contents of $string, or at least tells it not to bother recompiling):

    while (my $word = <DICT>) { chomp($word); if ($word =~ /$string/o) { $yep++; } }

    so that the regex won't be recompiled each time, as since there are variables in the regex, it forces a recompile, which will slow down your app quite a bit.

    Just my two cents.

      That seems like it would work, however, It will still not match the pattern. The regex doesn't seem to be working correctly using the code above. And I believe you need quotes around my $regex = "qr/$string/"; Like so. Lets say you have this:
      my $regex = "/[aeiou][aeiou]/";
      It tries to match the literal slash then bracket and so on..., not using it as a reg. ex. at all. I think it is taking the pattern to match literally, as in it is trying to match. If you leave off the quotes and you print the string, it isn't right.

        qr// is its own operator, and will not work with double quotes around it. If your regex variable ($string, in this case) that you will be pre-compiling has slashes in it, then of course it will try to match the slashes. It is assumed that the only thing inside the qr// operator is the regular expression itself. The previous posts before mine didn't contain slashes in their variable, either.

Re: Regular Expression Question
by jasonk (Parson) on Apr 03, 2003 at 18:15 UTC

    perlre explains why this is not permitted, and how to make it permitted if you really want to do it...

    $string =~ /$re/;
    
    Before Perl knew how to execute interpolated
    code within a pattern, this operation was com­
    pletely safe from a security point of view,
    although it could raise an exception from an
    illegal pattern.  If you turn on the "use re
    'eval'", though, it is no longer secure, so you
    should only do so if you are also using taint
    checking.  Better yet, use the carefully con­
    strained evaluation within a Safe module.  See
    perlsec for details about both these mechanisms.
    

    We're not surrounded, we're in a target-rich environment!
      perlre explains why this is not permitted

      Actually, perlre explains why (?{ code }) is not permitted which is quite a different thing.

      The original code worked exactly as expected for me with the addition of a closing ')' on the if statement. (The match fails to increment $yep because the 'v' in $word doesn't match the vowel pattern).

      Using variable interpolation in a regex is not a 'weird idea' at all. It can be an excellent way to improve the readability of your code.

      I don't get your answer. What does it have to do with the question?

      Abigail

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (2)
As of 2024-04-20 04:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found