Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

do $n exist in grep?

by misterperl (Monk)
on May 12, 2021 at 14:32 UTC ( #11132487=perlquestion: print w/replies, xml ) Need Help??

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

are the $n vars available somehow? in a statement like
grep /^..(A|B)./,@a;
Is $1 captured somewhere? It would be nice if $1 became an arrayref in this case?

BTW it seems inconsistent that the parens in this statement might be moot. Seems odd to have syntax there that is meaningless in this context. If $1 was returned as an arrayref, it would make good sense, vis-a-vis over-loading et all?

Replies are listed 'Best First'.
Re: do $n exist in grep?
by hippo (Chancellor) on May 12, 2021 at 14:37 UTC

    Not that I'm aware of. But you can always DIY:

    $ perl -E 'grep { /^..(A|B)./ and push @f, $1 } @ARGV; say @f' xxBxx y +yAyy BA $

    🦛

        or even easier

        DB<34> @a = qw/xxBxx yyAyy zzNzz/ DB<35> @N = map {/^..(A|B)./} @a DB<36> x @N 0 'B' 1 'A' DB<37>

        Hint: m// returns an empty list if there's no match

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      nice , TY u got an UPVOTE!
Re: do $n exist in grep?
by ikegami (Pope) on May 12, 2021 at 15:50 UTC
    map { /^..(A|B)./ ? [ $_, $1 ] : () } @a

    I got the sense that you didn't want just the captured parts. But if you only need the $1 from each match the above simplifies to

    map { /^..(A|B)./ ? $1 : () } @a

    but you could also go a step further and simply use

    map /^..(A|B)./, @a

    Update: Added what's after the break.

    Seeking work! You can reach me at ikegami@adaelis.com

      ikegami you are definitely a "blackbelt".

      I expanded your code to show relevance to the OP's question.
      Your map shows something that took me a long time to figure out,
      how to return "nothing" from a map{}!

      use strict; use warnings; my @x = ("aaBxyz", "..Bxys", "bbxyzzy", "xxAx"); my @result = map { /^..(A|B)./ ? [ $1, $_ ] : () } @x; # @result is a "2-d array", references to "rows of array" # I swapped $1 and $_ because I thought the print out looked better # Of course every map{} can be expressed as a for loop... foreach my $row_ref (@result) { print "@$row_ref\n"; } =PRINTS: B aaBxyz B ..Bxys A xxAx =cut
      I think this code is well past what the OP wanted.

      ADDED: If the OP wants a subset of something, think GREP. If the OP wants to transform an input into something else, think MAP.

        I use a similar idiom in formulating a return responses or external calls, sometimes:

        my ($stdout, $stderr, $ret) = capture { system('foo', ($somearg ? ('--somearg' => $somearg ) : ()), ($otherarg ? ('--otherarg' => $otherarg) : ()), ); };

        ...or...

        return { status => $s, ($optional_field ? (optional_field => $optional_field) : ()), };

        Caveat emptor. The need to do either of these may constitute code smell, but sometimes purity has to give way to get it done-ery.


        Dave

      I got the sense that you didn't want just the captured parts. But if you only need the $1 from each match,

      map { /^..(A|B)./ ? [ $_, $1 ] : () } @a

      simplifies to

      map { /^..(A|B)./ ? $1 : () } @a

      but you could also go a step further and simply use

      map /^..(A|B)./, @a

      (I added this to the original post to show the options in one place.)

      Seeking work! You can reach me at ikegami@adaelis.com

Re: do $n exist in grep?
by GrandFather (Saint) on May 12, 2021 at 21:17 UTC
    the parens in this statement might be moot

    Do you mean that the () in (A|B) is kinda bad because it captures A or B as well as acting to place a limit around A|B? If so you can (?:A|B) instead which groups A|B, but doesn't capture the match.

    If you mean something else, perhaps you would like to spell it out for us?

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: do $n exist in grep?
by Marshall (Canon) on May 12, 2021 at 15:19 UTC
    Grep could have been called "filter". But it is: "get regular expression".
    Use grep when you think about getting a subset of an array.
    use strict; use warnings; my @x = ("aaBxyz", "..Bxys", "bbxyzzy", "xxAx"); # for each element in the array @x, # pass that element to the array @result if # if the 3rd character is either A or B # followed by at least one character. my @result = grep {/^..(A|B)./}@x; print "$_\n" for @result; =prints aaBxyz ..Bxys xxAx =cut
    Yes, in this case $1 will be either A or B if the regex is True.
    I can show that, but I don't want to confuse you.
    Here $1 is not relevant.

    Ok, on second thought, here we go...

    #ok, with a weird example of $1 @result = grep{ print "$1 $_\n" if /^..(A|B)./; /^..(A|B)./}@x; =prints B aaBxyz B ..Bxys A xxAx =cut @result is the same as above # grep {} executes the code within the brackets and passes the input # to @result depending upon the true/false value of the last statement +.
Re: do $n exist in grep?
by Marshall (Canon) on May 12, 2021 at 18:00 UTC
    You wrote: Is $1 captured somewhere?

    I hope that this blizzard of replies to your post makes it clear that the parens do capture $1!

    Perl regex is super duper cool and there is a way to not capture A or B into $1. But I think that syntax is way past what you are asking for.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2021-06-18 11:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)












    Results (89 votes). Check out past polls.

    Notices?