How these $1 and $2 is decided?

Discussion in 'Perl Misc' started by yl, Nov 2, 2005.

  1. yl

    yl Guest

    Could anyone help explain this line of code?
    $_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]

    I think it can be divided into 3 parts
    1. (?>(.)?(.)+.*)
    2. (?!\1)
    3. (??{print(($1..$2)[15,4,17,11])})
    and the 3rd part will print 'PERL'. But I got no idea how the variables
    $1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
    not 'Z').

    Another question is that $_ is undef at program start, how could it
    become an array reference?

    Thanks.
     
    yl, Nov 2, 2005
    #1
    1. Advertising

  2. yl wrote:
    > Could anyone help explain this line of code?
    > $_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]
    >
    > I think it can be divided into 3 parts
    > 1. (?>(.)?(.)+.*)
    > 2. (?!\1)
    > 3. (??{print(($1..$2)[15,4,17,11])})
    > and the 3rd part will print 'PERL'. But I got no idea how the variables
    > $1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
    > not 'Z').


    $_->[] autovivifies an array reference so $_ becomes a text string something
    like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
    puts 'A' in $1 and 'R' in $2 giving the list 'A' .. 'R' from which the letters
    'P', 'E', 'R' and 'L' are sliced.

    > Another question is that $_ is undef at program start, how could it
    > become an array reference?


    Autovivification.


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Nov 2, 2005
    #2
    1. Advertising

  3. yl

    yl Guest

    John W. Krahn 寫é“:

    >
    > $_->[] autovivifies an array reference so $_ becomes a text string something
    > like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)


    The $_->[/regex/] thing looks quite strange to me. I never thought a
    regex can be placed in a bracket like this. Is it a useful expression
    that I can use in many situations or just for demonstration of an
    advanced Perl skill?

    Thanks
     
    yl, Nov 2, 2005
    #3
  4. yl wrote:
    > John W. Krahn 寫é“:
    >
    >>$_->[] autovivifies an array reference so $_ becomes a text string something
    >>like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)

    >
    > The $_->[/regex/] thing looks quite strange to me. I never thought a
    > regex can be placed in a bracket like this. Is it a useful expression
    > that I can use in many situations or just for demonstration of an
    > advanced Perl skill?


    In the example the regex wasn't used for its return value but for the side
    effect of the print function.

    An example of a useful use of a regex in an array slice:

    my @array = 'a' .. 'z';

    $_ = ' 14 1 5 20 18 2 0 19 4 ';

    print @a[ /\d+/g ], "\n";



    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Nov 2, 2005
    #4
  5. [A complimentary Cc of this posting was sent to
    John W. Krahn
    <>], who wrote in article <FLX9f.73947$S4.15830@edtnps84>:
    > yl wrote:
    > > Could anyone help explain this line of code?
    > > $_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]
    > >
    > > I think it can be divided into 3 parts
    > > 1. (?>(.)?(.)+.*)
    > > 2. (?!\1)
    > > 3. (??{print(($1..$2)[15,4,17,11])})
    > > and the 3rd part will print 'PERL'. But I got no idea how the variables
    > > $1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
    > > not 'Z').

    >
    > $_->[] autovivifies an array reference so $_ becomes a text string something
    > like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
    > puts 'A' in $1 and 'R' in $2 giving the list 'A' .. 'R' from which the letters


    Are you sure? Actually, $2 is ')'.

    perl -wle "[1] =~ /^(?>(.)?(.)+.*)(?!\1)/ and print $2"
    )

    Looks like the .. operator (as opposed to ++ !!!) has alphanumeric
    *output*, but arbitrary *input*: here 'A' .. ')' is the same as 'A' .. 'Z'.
    Probably won't be so on EBCDIC.

    Hope this helps,
    Ilya
     
    Ilya Zakharevich, Nov 2, 2005
    #5
  6. yl

    Anno Siegel Guest

    John W. Krahn <> wrote in comp.lang.perl.misc:
    > yl wrote:
    > > John W. Krahn 寫é“:
    > >
    > >>$_->[] autovivifies an array reference so $_ becomes a text string something
    > >>like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)

    > >
    > > The $_->[/regex/] thing looks quite strange to me. I never thought a
    > > regex can be placed in a bracket like this. Is it a useful expression
    > > that I can use in many situations or just for demonstration of an
    > > advanced Perl skill?

    >
    > In the example the regex wasn't used for its return value but for the side
    > effect of the print function.
    >
    > An example of a useful use of a regex in an array slice:
    >
    > my @array = 'a' .. 'z';

    ^^^^^
    >
    > $_ = ' 14 1 5 20 18 2 0 19 4 ';
    >
    > print @a[ /\d+/g ], "\n";

    ^
    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Nov 2, 2005
    #6
  7. Anno Siegel wrote:
    > John W. Krahn <> wrote in comp.lang.perl.misc:
    >>yl wrote:
    >>>John W. Krahn 寫é“:
    >>>
    >>>>$_->[] autovivifies an array reference so $_ becomes a text string something
    >>>>like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
    >>>The $_->[/regex/] thing looks quite strange to me. I never thought a
    >>>regex can be placed in a bracket like this. Is it a useful expression
    >>>that I can use in many situations or just for demonstration of an
    >>>advanced Perl skill?

    >>In the example the regex wasn't used for its return value but for the side
    >>effect of the print function.
    >>
    >>An example of a useful use of a regex in an array slice:
    >>
    >>my @array = 'a' .. 'z';

    > ^^^^^
    >>$_ = ' 14 1 5 20 18 2 0 19 4 ';
    >>
    >>print @a[ /\d+/g ], "\n";

    > ^


    Oops, sorry, I copied and pasted the wrong code, it should be:

    my @array = 'a' .. 'z';

    $_ = ' 14 1 5 20 18 2 0 19 4 ';

    print @array[ /\d+/g ], "\n";




    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Nov 2, 2005
    #7
  8. Ilya Zakharevich wrote:
    > [A complimentary Cc of this posting was sent to
    > John W. Krahn
    > <>], who wrote in article <FLX9f.73947$S4.15830@edtnps84>:
    >>yl wrote:
    >>>Could anyone help explain this line of code?
    >>>$_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]
    >>>
    >>>I think it can be divided into 3 parts
    >>>1. (?>(.)?(.)+.*)
    >>>2. (?!\1)
    >>>3. (??{print(($1..$2)[15,4,17,11])})
    >>>and the 3rd part will print 'PERL'. But I got no idea how the variables
    >>>$1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
    >>>not 'Z').

    >>$_->[] autovivifies an array reference so $_ becomes a text string something
    >>like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
    >>puts 'A' in $1 and 'R' in $2 giving the list 'A' .. 'R' from which the letters

    >
    > Are you sure? Actually, $2 is ')'.
    >
    > perl -wle "[1] =~ /^(?>(.)?(.)+.*)(?!\1)/ and print $2"
    > )
    >
    > Looks like the .. operator (as opposed to ++ !!!) has alphanumeric
    > *output*, but arbitrary *input*: here 'A' .. ')' is the same as 'A' .. 'Z'.
    > Probably won't be so on EBCDIC.


    That is weird. According to perlop: "If the left value is greater than the
    right value then it returns the empty list.". And 'A' gt ')' (at least in
    ASCII) so it should be an empty list.


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Nov 2, 2005
    #8
  9. yl <> wrote:

    > The $_->[/regex/] thing looks quite strange to me. I never thought a
    > regex can be placed in a bracket like this.



    It is nothing more than a m// in a list context.


    > Is it a useful expression
    > that I can use in many situations



    Yes, m// in a list context is often useful.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Nov 2, 2005
    #9
  10. yl

    Vronans Guest

    John W. Krahn wrote:
    > Anno Siegel wrote:
    >> John W. Krahn <> wrote in comp.lang.perl.misc:
    >>> yl wrote:
    >>>> John W. Krahn 寫é“:
    >>>>
    >>>>> $_->[] autovivifies an array reference so $_ becomes a text
    >>>>> string something like ARRAY(0x12345678) which the regex operates
    >>>>> on. ^(?>(.)?(.)+.*)(?!\1)
    >>>> The $_->[/regex/] thing looks quite strange to me. I never thought
    >>>> a regex can be placed in a bracket like this. Is it a useful
    >>>> expression that I can use in many situations or just for
    >>>> demonstration of an advanced Perl skill?
    >>> In the example the regex wasn't used for its return value but for
    >>> the side effect of the print function.
    >>>
    >>> An example of a useful use of a regex in an array slice:
    >>>
    >>> my @array = 'a' .. 'z';

    >> ^^^^^
    >>> $_ = ' 14 1 5 20 18 2 0 19 4 ';
    >>>
    >>> print @a[ /\d+/g ], "\n";

    >> ^

    >
    > Oops, sorry, I copied and pasted the wrong code, it should be:
    >
    > my @array = 'a' .. 'z';
    >
    > $_ = ' 14 1 5 20 18 2 0 19 4 ';
    >
    > print @array[ /\d+/g ], "\n";


    Even though it wasn't very difficult (for some of us) to mentally
    translate it anyway :p
     
    Vronans, Nov 2, 2005
    #10
  11. yl

    Guest

    "yl" <> wrote:
    > John W. Krahn =E5=AF=AB=E9=81=93=EF=BC=9A
    >
    > >
    > > $_->[] autovivifies an array reference so $_ becomes a text string
    > > someth=

    > ing
    > > like ARRAY(0x12345678) which the regex operates on.
    > > ^(?>(.)?(.)+.*)(?!\1)

    >
    > The $_->[/regex/] thing looks quite strange to me. I never thought a
    > regex can be placed in a bracket like this.


    Any expression can go in the bracket. What is in the bracket is not
    a bare regex, it is an expression, which in this case happens to consist of
    a regex operator (m//). The operator is operating on a regex, but it is
    not itself a regex.


    > Is it a useful expression
    > that I can use in many situations or just for demonstration of an
    > advanced Perl skill?


    The particular code you posted would be better described as deranged than
    advanced. It is intentionally obfuscated. I have never needed to use a
    the result of a regex operator as an array index, but I can't gaurantee it
    will never ever be useful for someone to do it.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Nov 2, 2005
    #11
  12. yl

    Paul Lalli Guest

    Stan R. wrote:
    > Isn't it because the m// in list context (used inside [...]'s) gives you
    > a slice ?


    m// in list context gives you a list. Nothing more. Specifically, it
    is a list of all the captured sub matches (or the list of all global
    matches if /g is used).

    [ ], when applied to an existing array or list, gives you a slice.

    > Like this bit of code I wrtoe a while back, to make a simple ascii2hex
    > script:
    >
    > my @a = \x01..\xFF;
    > $_ = '(1,2,3),(20,15,10)';
    > my %h = map{$_=>sprintf('0x%02X',ord($_))}@a[m!\d+!g];
    > print "$_ = $h{$_}\n" foreach (sort keys %h);
    >
    > __OUTOUT__
    > 1 = 0x31
    > 2 = 0x32
    > 3 = 0x33
    > a = 0x61
    > b = 0x62
    > c = 0x63


    Odd, when I run that code, I get:
    Bareword "xFF" not allowed while "strict subs" in use at ./clpm.pl line
    4.
    Bareword "x01" not allowed while "strict subs" in use at ./clpm.pl line
    4.

    After I correct that error (\x01 ==> 0x01, \xFF ==> 0xFF), I get:
    11 = 0x31
    16 = 0x31
    2 = 0x32
    21 = 0x32
    3 = 0x33
    4 = 0x34

    Your m!\d+!g expression returned a list of all digit sequences from $_,
    namely 1, 2, 3, 20, 15, 10. It then used these as the indices for a
    slice of @a, which contained all the numbers from 1 to 255. Except
    that the element of @a with index 1 is 2, index 2 is 3, etc. Arrays in
    Perl are 0-indexed.

    So the list that map{} was operating on was (2, 3, 4, 21, 16, 11). For
    each element of this list, you created a key-value pair where the key
    is the element itself, and the value is the ASCII value of the first
    character of the element (1 for 11, 1 for 16, 2 for 2, 2 for 21, etc),
    translated to hex.

    I see no way for your code to produce the results you claimed you
    received.

    Paul Lalli
     
    Paul Lalli, Nov 2, 2005
    #12
  13. yl

    Guest

    Tad McClellan <> wrote:
    > yl <> wrote:
    >
    > > The $_->[/regex/] thing looks quite strange to me. I never thought a
    > > regex can be placed in a bracket like this.

    >
    > It is nothing more than a m// in a list context.


    That seems like a scalar context.

    $ perl -le 'sub foo {print wantarray ? "list":"scalar"}; $_->[foo()]'
    scalar

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Nov 2, 2005
    #13
  14. yl

    Paul Lalli Guest

    wrote:
    > Tad McClellan <> wrote:
    > > yl <> wrote:
    > >
    > > > The $_->[/regex/] thing looks quite strange to me. I never thought a
    > > > regex can be placed in a bracket like this.

    > >
    > > It is nothing more than a m// in a list context.

    >
    > That seems like a scalar context.
    >
    > $ perl -le 'sub foo {print wantarray ? "list":"scalar"}; $_->[foo()]'
    > scalar


    It is. $_->[ ] is a scalar value, as you're grabbing a single value
    from the array ref. If you grab a slice from the array ref, on the
    other hand...

    $ perl -le 'sub foo {print wantarray ? "list":"scalar"}; ${$_}[foo()]'
    scalar
    $ perl -le 'sub foo {print wantarray ? "list":"scalar"}; @{$_}[foo()]'
    list

    Paul Lalli
     
    Paul Lalli, Nov 2, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Arjen Hoekstra
    Replies:
    0
    Views:
    565
    Arjen Hoekstra
    Aug 2, 2005
  2. Luigi Donatello Asero

    Are these pictures too dark or/and too large?

    Luigi Donatello Asero, May 19, 2004, in forum: HTML
    Replies:
    13
    Views:
    922
    Mabden
    May 21, 2004
  3. Luigi Donatello Asero

    Re: Are these pictures too dark or/and too large?

    Luigi Donatello Asero, May 21, 2004, in forum: HTML
    Replies:
    0
    Views:
    653
    Luigi Donatello Asero
    May 21, 2004
  4. Heather Stovold

    So many things that need to be decided....

    Heather Stovold, May 3, 2005, in forum: Python
    Replies:
    14
    Views:
    535
    Mike Meyer
    May 6, 2005
  5. Alexander
    Replies:
    20
    Views:
    1,056
    BGB / cr88192
    Sep 11, 2010
Loading...

Share This Page