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

I want to iterate over a hash and for every key/value pair, do a s/key/value/. I can make the key match by creating the entry with the key as qr/(word)/, but I can't get the $1 to evaluate in the value portion. If I store it as $hash{key}='$1' then I (obviously) get literally $1 in the output. If I store it as $hash{key}="$1" then $1 holds the value of the previous match. What can I do so that $1 is interpolated when the s/// is run?

Replies are listed 'Best First'.
Re: Making a hash of regexes
by Ovid (Cardinal) on Nov 25, 2002 at 20:24 UTC

    Can you show us a code snippet? What are you trying to do the substitution on? The following works, but I think it's not what you are asking for.

    #!/usr/bin/perl -w use strict; my %hash = ( foo => 'bar', baz => 'quux' ); my $string = 'foo and baz'; while( my($k,$v) = each %hash ) { $string =~ s/$k/$v/g; } print $string;

    What I'm asking is: "what is your substitution target"? Are you trying to simply make substitutions in a string, like I did above, or are you trying to munge hash keys or something strange like that?

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

      I'm trying to substitute psudo-html into html. It would convert this string: [h2]Test[/h2] [h3]Test[/h3] into <h2>Test</h2> <h3>Test</h3>. This is what the code looks like inside my program:
      # Create a hash of codes for substitution my %directSubs = ( qr/\[h(\d)\]/ => '<h$1>', qr/\[\/h(\d)\]/=> '</h$1>' ); # Substitute the codes while(($a,$b) = each %directSubs){ $line =~ s/$a/$b/gi; }

        One way

        #! perl -slw use strict; my $pseudo = '[h2]Test[/h2] [h3]Test[/h3]'; # Create a hash of codes for substitution my %directSubs = ( qr/\[h(\d)\]/ => '"<h$1>"', qr/\[\/h(\d)\]/=> '"</h$1>"' ); # Substitute the codes while(($a,$b) = each %directSubs){ $pseudo =~ s/$a/$b/giee; } print $pseudo; __END__ # Output C:\test>215723 <h2>Test</h2> <h3>Test</h3> C:\test>

        Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
        Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
        Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
        Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: Making a hash of regexes
by steves (Curate) on Nov 25, 2002 at 21:06 UTC
    qr creates a Regexp reference. You can't use references as hash keys unless you tie the hash using Tie::RefHash. That may not be your problem here but you'll need to fix that.
      Actually, from man perlop:
      qr/STRING/imosx
         This operator quotes (and possibly compiles) its
         STRING as a regular expression.  STRING is inter­
         polated the same way as PATTERN in "m/PATTERN/".
         If "'" is used as the delimiter, no interpolation
         is done.  Returns a Perl value which may be used
         instead of the corresponding "/STRING/imosx"
         expression.
      
      A little experiment:
      use strict my %a = (qr/(.+)pippo/, 1); print keys %a;
      prints out (?-xism:(.+)pippo), which can be used in the matching part of a regex, while
      use strict; my %a = (1,2); my %b = (\%a, 3); for (keys %b) { print %$_ };
      dies with error
      Can't use string ("HASH(0x81005ac)") as a HASH ref while "strict refs" in use at - line 5.

      The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket
      Ok, I'm confused. I made the corrections and it works fine now, with no errors even using the strict and warning pragmas. Shouldn't it fail to work?

      qr creates a Regexp reference.

      I've never heard of a regex reference? Could you give me a pointer to the docs on that?


      Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
      Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
      Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
      Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.