Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Bug with "last successfully matched regular expression" (empty regex)

by LanX (Canon)
on Feb 22, 2012 at 01:04 UTC ( #955426=perlquestion: print w/ replies, xml ) Need Help??
LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

could someone please be so kind to explain me the difference between line 137 and line 140?

DB<136> @list= ("a".."c","DBIC","A".."C","DANCER","a".."c") => ("a", "b", "c", "DBIC", "A", "B", "C", "DANCER", "a", "b", "c") DB<137> for (@list) { push @result,$_ if /DBIC/.. /DANCER/ and ! // + } => "" DB<138> @result => ("A", "B", "C") DB<139> grep { /DBIC/.. /DANCER/ and // } @list => ("DBIC", "A", "B", "C", "DANCER") DB<140> grep { /DBIC/.. /DANCER/ and ! // } @list => ()

For an explanation of the empty regex // please see Re: grep trouble and Re^4: grep trouble (body of flip-flop range).

Cheers Rolf

Comment on Bug with "last successfully matched regular expression" (empty regex)
Select or Download Code
Re: Bug with "last successfully matched regular expression" (empty regex)
by Anonymous Monk on Feb 22, 2012 at 01:43 UTC

    Looks like a bug to me, whatever special casing .... doesn't happen the same way with grep
    $ perl -Mre=debug -le " @F = qw( a b c DBIC A B C DANCER a b c ); for( +@F){print if /DBIC/.. /DANCER/ and ! // } " Compiling REx "DBIC" Final program: 1: EXACT <DBIC> (3) 3: END (0) anchored "DBIC" at 0 (checking anchored isall) minlen 4 Compiling REx "DANCER" Final program: 1: EXACT <DANCER> (4) 4: END (0) anchored "DANCER" at 0 (checking anchored isall) minlen 6 Compiling REx "" Final program: 1: NOTHING (2) 2: END (0) minlen 0 Guessing start of match in sv for REx "DBIC" against "DBIC" Found anchored substr "DBIC" at offset 0... Guessed: match at offset 0 Guessing start of match in sv for REx "DBIC" against "DBIC" Found anchored substr "DBIC" at offset 0... Guessed: match at offset 0 A B C Guessing start of match in sv for REx "DANCER" against "DANCER" Found anchored substr "DANCER" at offset 0... Guessed: match at offset 0 Guessing start of match in sv for REx "DANCER" against "DANCER" Found anchored substr "DANCER" at offset 0... Guessed: match at offset 0 Freeing REx: "DBIC" Freeing REx: "DANCER" Freeing REx: ""
    $ perl -Mre=debug -le " @F = qw( a b c DBIC A B C DANCER a b c ); prin +t for grep { /DBIC/.. /DANCER/ and ! // } @F; " Compiling REx "DBIC" Final program: 1: EXACT <DBIC> (3) 3: END (0) anchored "DBIC" at 0 (checking anchored isall) minlen 4 Compiling REx "DANCER" Final program: 1: EXACT <DANCER> (4) 4: END (0) anchored "DANCER" at 0 (checking anchored isall) minlen 6 Compiling REx "" Final program: 1: NOTHING (2) 2: END (0) minlen 0 Guessing start of match in sv for REx "DBIC" against "DBIC" Found anchored substr "DBIC" at offset 0... Guessed: match at offset 0 Guessing start of match in sv for REx "DBIC" against "DBIC" Found anchored substr "DBIC" at offset 0... Guessed: match at offset 0 Matching REx "" against "A" 0 <> <A> | 1:NOTHING(2) 0 <> <A> | 2:END(0) Match successful! Matching REx "" against "B" 0 <> <B> | 1:NOTHING(2) 0 <> <B> | 2:END(0) Match successful! Matching REx "" against "C" 0 <> <C> | 1:NOTHING(2) 0 <> <C> | 2:END(0) Match successful! Guessing start of match in sv for REx "DANCER" against "DANCER" Found anchored substr "DANCER" at offset 0... Guessed: match at offset 0 Guessing start of match in sv for REx "DANCER" against "DANCER" Found anchored substr "DANCER" at offset 0... Guessed: match at offset 0 Freeing REx: "DBIC" Freeing REx: "DANCER" Freeing REx: ""

Re: Bug with "last successfully matched regular expression" (empty regex)
by Marshall (Prior) on Feb 22, 2012 at 04:43 UTC
    I also could not get this !// thing to work in the grep. I am mystified why it doesn't, but I did recode according to Flipin good, or a total flop? which tests the value of the flip-flop regex and this does work in a grep. Just a point of reference:
    #!/usr/bin/perl -w use strict; use Data::Dumper; my @list= ("a".."c","DBIC","A".."C","DANCER","a".."c"); my @result; for (@list) { push @result,$_ if /DBIC/.. /DANCER/ and ! // } print Dumper \@result; # uses http://www.perlmonks.org/?node_id=525392 my @result2 = grep { (/DBIC/.. /DANCER/) =~ /^\d+(?<!^1)$/ }@list; print Dumper \@result2; __END__ $VAR1 = [ 'A', 'B', 'C' ]; $VAR1 = [ 'A', 'B', 'C' ];
    The value of the flip-flop regex returns a line number like: 1,2,3,4E0 and that number can be tested in another regex.

    As another note this "xE0" notation is used in other places in Perl. For example, the DBI can return 0E0 as the number of results which is 0 * 10**0 or numeric zero (0 * 1) although this evaluates to "true" when tested in a logical sense, meaning that that the statement "worked" but returned no results (numeric value is zero). Here the line number ending in E0 is the "last one". This is clever but it works.

      Good catch, but the whole implementation is annoyingly inconsistent.

      I thought I could make this more obvious by implementing functions like nodege(), noflip(), and noflop() to write something like

      grep { noedge(/DBIC/ .. /DANCER/)  }@list;

      but try guessing which magic behavior hinders that:

      DB<52> @list= ("a".."c","DBIC","A".."C","DANCER","a".."c"); DB<53> sub ff { print $_[0]} DB<54> grep { ff(/DBIC/ .. /DANCER/) } @list; 0000000000 DB<55> grep { my $x=(/DBIC/ .. /DANCER/); ff($x) } @list; 12345E0

      Of course I could also use something like compiled regexes for EDGE, FLIP, FLOP to be able to type something like:

      grep { (/DBIC/ .. /DANCER/) !~ EDGE  } @list;

      but that doesn't seem to be trivial, too :-(

      Thanks anyway!

      Cheers Rolf

        ARGH!!!!!!!!!

        DB<52> @list= ("a".."c","DBIC","A".."C","DANCER","a".."c"); DB<53> sub ff { print $_[0]} DB<54> grep { ff(/DBIC/ .. /DANCER/) } @list; 0000000000 DB<55> grep { my $x=(/DBIC/ .. /DANCER/); ff($x) } @list; 12345E0

        ff() evaluates the range operator in list context!

        applying prototypes solves this "problem":

        DB<182> @list= ("a".."c","DBIC","A".."C","DANCER","a".."c"); DB<183> sub ff ($) { print $_[0]} DB<184> grep { ff(/DBIC/ .. /DANCER/) } @list; 12345E0

        Cheers Rolf ( ...banging his head against the table...)

      That doesn't work if DBIC appears multiple times (which it can).
Re: Bug with "last successfully matched regular expression" (empty regex) (scope)
by tye (Cardinal) on Feb 22, 2012 at 05:44 UTC

    Regex match information has a somewhat complex interaction with lexical scope. The 'grep' case fails because the scope of the expression is left and re-entered. The 'for' case succeeds because the scope of the body of the 'for' is never effectively left/entered during the running of the loop (where what "effectively" means is intentionally vague).

    My evidence to support this claim is that adding another block of scope to the 'for' loop breaks it as well:

    use strict; my $if = 1; my @list= ("a".."c","DBIC","A".."C","DANCER","a".."c"); my @result; for (@list) { if( $if ) { # Comment this out push @result,$_ if /DBIC/.. /DANCER/ and ! //; } # Comment this out } print $_, $/ for @result; __END__

    Comment out the two indicated lines to again see A .. C output. As is, the above code outputs nothing (similar to the 'grep' case).

    - tye        

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-12-26 09:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (171 votes), past polls