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

I have a regexp with backreferences, and I have a variable that holds the number of backreferences. Observe:
use warnings; use strict; #.... $_ = 'foobarbaz'; my $backrefcount = 3; /(f.o)(b.r)(b.z)/; foreach (1..$backrefcount) { no strict; print ${$_}."\n"; }
(FYI, what I actually have is a snippet that counts the number of backreferences in a pattern, and then concat's each backreference value into one string.)

I was curious if there's a way to do this while keeping the strict pragma active. I found one node (http://www.perlmonks.org/index.pl?node_id=35531) that seemed sort of along the lines of what I need, but I couldn't figure out how to apply it to what I'm doing.

Replies are listed 'Best First'.
Re: accessing backreferences
by merlyn (Sage) on Mar 09, 2001 at 23:03 UTC
    Don't access the backreferences from there... save them in a list as a result of the match. (Your way is dangerous if the match fails, by the way.)
    use strict; if (my @matches = /(f.o)(b.r)(b.z)/) { print "Match # $_ is $matches[$_-1]\n" for 1..@matches; }

    -- Randal L. Schwartz, Perl hacker

      it actually IS like that, i just scratched up that example for... well, for example. i always use some kind of if statement to check a match before hitting backreferences.
Re: accessing backreferences
by arturo (Vicar) on Mar 09, 2001 at 23:05 UTC

    The problem I take it you're running into is that

    print ${$_},"\n";
    Produces a warning under use strict (specifically, under  use strict 'refs'). You CAN turn off strict refs in a block with
    { no strict 'refs'; # stuff }
    But you're probably better off loading your captured backreferences into an array, and then looping through the array , e.g.:
    my @bits = /(f.o)(b.r)(b.z)/; foreach (@bits) { print "$_\n"; }

    HTH.

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      holy crap you can do that?! (checks real quick) DUDE! that's exactly what i was looking for, thanks.
Re: accessing backreferences
by YaRness (Initiate) on Mar 09, 2001 at 23:02 UTC
    BTW that's me (YaRness) if anyone cares, i seem to still be having issues with staying logged in. I think i just needed to add the .com and .org for perlmonks to my junkbuster file.
Re: accessing backreferences
by InfiniteSilence (Curate) on Mar 09, 2001 at 23:21 UTC
    Your problem is that $1...$3 are not indices in an array, but are read-only scalar variables generated by the system. Thus, $1 is not at all the same as $[1] (heh, heh) or something like that.

    You want to use eval() to convert your iterator into something usable, like so:

    perl -e "$a = qq(foo); $a =~ m/(foo)/; $s = 1; $xx = eval('\$$s');pri +nt $$xx; "

    Celebrate Intellectual Diversity

      No, that's about as wrong as you can get. Don't use eval for that. See the other solutions in this thread for maintainable, workable, speedy, safe solutions.

      -- Randal L. Schwartz, Perl hacker