in reply to regex eval capture weirdness

It's a closure problem (which I don't understand well). The fix looks like:

sub domatch { my ($str, $regex) = @_; our %mv; # Note the our return 0 if $str !~ /$regex/; return \%mv if keys %mv != 0; print "No keys in hash.\n"; return 0; }

Which in the context of your sample code prints:

original pseudo-regex: test_%a%b modified regex: test_(\d{2})(?{$mv{a} = $^N })(\d{4})(?{$mv{b} = $^N } +) Matching on test_001022 Result: a => 00 b => 1022 Matching on test_585381 Result: a => 58 b => 5381 Matching on test_389742 Result: a => 38 b => 9742 Matching on test_330104 Result: a => 33 b => 0104

Neat trick with the (?{...$^N}) BTW.


DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: regex eval capture weirdness
by Tanktalus (Canon) on Dec 01, 2005 at 00:28 UTC

    GrandFather, minor quibble. Take the output section and change it to:

    my @results = map { [$_ => domatch($_, $r)] } @strings; #foreach my $str (@strings) { foreach my $r (@results) { my ($str, $result) = @$r; print "Matching on $str\n"; #my $result = domatch($str,$r); if ($result) { print "Result:\n"; foreach my $k (keys %{$result}) { print "\t$k => $result->{$k}\n"; } } else { print "No match.\n"; } }
    And notice it stop working. Well, notice it give the last result for all the matches. Now change your code to return { %mv } if keys %mv != 0 and notice it start working again.

    It is bizarre ... and I'm hoping someone more familiar with the regexp engine internals will pipe up as to why this isn't DWIMming very well. I tried a number of different changes to try to get the engine to think I was doing another match, but failed, perhaps someone else will see what we're missing. In this way, I wouldn't (yet) call what you did a "fix" but more of a "workaround" ;-)

      Yes, "fix" was overstating the case somewhat in light of the level of understanding involved.

      Take a look the this discussion. It's the same problem. The issue is that the compilation of the (?{...}) in the regex creates a closure on %mv and the second time through the sub the my %mv; creates a different instance of %mv which is not the one the regex is using.

      Now I've told the teddy bear I understand the problem and why our works - at least until I get back to my desk. :)


      DWIM is Perl's answer to Gödel
Re^2: regex eval capture weirdness
by bytex64 (Novice) on Dec 01, 2005 at 20:03 UTC

    Ah, very nice. That works great. Thanks for everyone's help, I've been banging my head against the wall over this for days. :)