Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Finding the right $<*digit*> capture variable

by tekkie (Beadle)
on Apr 16, 2003 at 14:07 UTC ( [id://250901]=note: print w/replies, xml ) Need Help??


in reply to Finding the right $<*digit*> capture variable

I'm not sure where you're going with this either, $#- probably does what you're looking for.

You could also write a subroutine to check which $<DIGIT> values are defined, and return the last one found:
sub last_match { # Accepts no args # Returns the digit of the last parenthesis match or undef if ther +e isn't one my $match_num = 1; if(defined($$match_num)) { while(defined($$match_num)) { $match_num++; } $match_num--; } else { undef $match_num; } return $match_num; }

Replies are listed 'Best First'.
Re: Re: Finding the right $<*digit*> capture variable
by hv (Prior) on Apr 17, 2003 at 13:26 UTC

    Beware that this approach cannot discover the last defined match variable, since there may be gaps in the list: for example after "b" =~ /(a)?(b)/, $1 will not be defined even though $2 is.

    Since there is no useful absolute limit on the highest numbered match variable you might need to check for, I wondered whether walking the symbol table might give a clue, but no such luck - the symbol table entries for *1 etc are created only if they are explicitly referenced in the code:

    "abcde" =~ /(.)(.)(.)(.)(.)/; my $var = $4; print join ', ', grep !/\D/, keys %::;
    prints "0, 4".

    Accordingly, I think it is not possible in pure perl to discover the highest numbered defined match variable using any perl before v5.6.0 (when @+ and friends were first introduced).

    Hugo

      I was thinking of taking the sideways route - instrument the ')' part of a '(...)' group so that the contents of @+ is copied elsewhere for safekeeping. Any time that I'm interested in knowing which newly closed group was just passed I'd look for the index of the newly defined value in @+.

      So after (a)? $+[1] and $+[2] are undefined. After (b) $+[1] is still undefined but $+[2] is defined (and equal to 2). So... if I can know which @+ entry was just created is that sufficient or will that break as well?

        I think you can combine the information from @-, @+ and $^N to get most of the way there:

        sub last_closed { my $last = $+[0]; my $len = length $^N; for (1 .. $#+) { return $_ if defined($+[$_]) && $+[$_] == $last && $+[$_] == $len + $-[$_]; } return undef; } "ad" =~ m{ ( (a) (?{ print last_closed() }) (b)? (?{ print last_closed() }) (c?) (?{ print last_closed() }) d ) (?{ print last_closed() }) }x;

        This assumes a capture has just been closed; if that isn't necessarily the case, $last should instead be calculated as max(@+[1 .. $#+]).

        Obviously this cannot report optional captures that did not capture; also, it can't tell the order of closing of empty strings - "c" =~ /((a*)b*)/ vs "c" =~ /(a*)(b*)/ - but if you are only interested in non-empty captures, I think this code will give the unique answer.

        Hugo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://250901]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-03-29 10:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found