[EMAIL PROTECTED] (Daniel Kidger) wrote on 13 Nov 2001:
> 
> I have a pattern like
>    $hosts = "fred[1,3-7,9-22]"
> 
> Is there a simple way to generate an expanded list like:
>    fred1 fred3 fred4 fred5 ... 

*If* you can trust your input, here's a quick way:

use strict;
use warnings;

my $str = 'fred[1,3-7,9-22]';
if ( $str =~ /\[([^]]+)]/ ) {
   my  $numtext = $1;
   $numtext =~ s/-/../g;
   print "fred$_\n" for eval $numtext;
}
__END__


The following is safer, although I still don't guarantee I haven't 
overlooked something.

use strict;
use warnings;

my $str = q{fred[,1,system "arbitary command",3--hi--7,9-\\ 22,--,99-
     ---101----200, 45-40,,,-]};
# assuming all numbers are positive integers
if ( $str =~ /\[([^]]+)]/ ) {
    my  $number_text = $1;
    $number_text =~ tr/0-9,\-//cd; # delete unexpected characters
    $number_text =~ s/,+/,/g;   # delete extra commas
    $number_text =~ s/-+/-/g;   # delete extra dashes
    $number_text =~ s/^[,-]+//; # delete commas and dashes at string start
    $number_text =~ s/[,-]+$//; # delete commas and dashes at string end
    $number_text =~ s/-*,-*/,/g;# no dashes next to commas
    my @range_list = split /,/, $number_text;
    for my $range (@range_list) {
        # plain integer?  print it and go to the next one
        print("fred$range\n"), next if $range =~ /^\d+$/;
        
        # skip if it isn't number-dash-number
        next if $range !~ /^(\d+)-(\d+)$/;
        
        my ($start, $end) = ($1, $2);
        if ($start <= $end) {
            print "fred$_\n" for $start .. $end;
        }
    }
}
__END__

-- 
David Wall
[EMAIL PROTECTED]

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to