in reply to Need a better way to break out a range of addresses...

An example using Set::CrossProduct

#!/usr/bin/perl use strict; use warnings; use Set::CrossProduct; while (<DATA>) { chomp; s/\s*#.+//; my @data; while (/([^.]+)/g) { if ($1 =~ /(\d+)-(\d+)/) { push @data, [$1..$2]; } else { push @data, [$1]; } } for (Set::CrossProduct->new( \@data )->combinations) { print join(".", @$_), "\n"; } } __DATA__ 172.17.119.2 # Comments are here... 172.17.119.4-5 # Comments are here... 172.19-21.254.2-3 # Comments are here... 192.168.1.1-3 # Comments are here...

Chris

Replies are listed 'Best First'.
Re^2: Need a better way to break out a range of addresses...
by brian_d_foy (Abbot) on Mar 29, 2007 at 04:18 UTC

    Nice use of Set::CrossProduct! Note, however, that if the data set is large you might want to stick with the get method. The combinations method generates all of the combinations at once and returns a big list, whereas get just gives a new combination without creating the big list internally. There's no need for fancy HOP magic or nested loops (that you have to think about, anyway :)

    #!/usr/bin/perl use strict; use warnings; use Set::CrossProduct; while( <DATA> ) { chomp; s/\s*#.*//; my @b = map { [ m/(\d+)-(\d+)/ ? $1 .. $2 : $_ ] } split /\./; my $cross = Set::CrossProduct->new( \@b ); while( my $array_ref = $cross->get ) { print join( ".", @$array_ref ), "\n"; } } __END__ 172.17.119.2 # Comments are here... 172.17.119.4-5 # Comments are here... 172.19-21.254.2-3 # Comments are here... 192.168.1.1-3 # Comments are here...

    And, just for giggles and since I already wrote it before I saw your post, my version of the same program that you wrote, but mostly as a list pipeline:

    #!/usr/bin/perl use strict; use warnings; use Set::CrossProduct; $, = "\n"; print map { chomp; s/\s*(#.*)?$//; map { join ".", @$_ } Set::CrossProduct->new( [ map { [ m/(\d+)-(\d+)/ ? $1 .. $2 : $_ ] } split /\./ ] )->combinations; } <DATA>; __END__ 172.17.119.2 # Comments are here... 172.17.119.4-5 # Comments are here... 172.19-21.254.2-3 # Comments are here... 192.168.1.1-3 # Comments are here...
    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
      It wasn't so easy to see the solution at first. I shut the computer off and went for an easy chair to try and figure it out. I could see that I wanted all combinations of the values that expressed a range but I didn't know how to generate them. Then, it occurred to me that the values that were just one number were also a set - a set of one. So then, the solution came to me!

      CPAN - what a treasure!