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

Thanks in advance for your assistance!

I would like to convert a string containing number ranges to an array. Here is an example string:

$string = "1,5,7..10,15,17..19,22";

I would like to convert $string to an @array that would have the following keys and values:

(key -> value)
0 -> 1
1 -> 5
2 -> 7
3 -> 8
4 -> 9
5 -> 10
6 -> 15
7 -> 17
8 -> 18
9 -> 19
10 -> 22

Normally, I would go with the split() function and separate on the commas, but I cannot figure out how to get the ranges to fill in the array properly.

Many thanks!

Replies are listed 'Best First'.
Re: Converting String Containing Ranges to Array
by kennethk (Abbot) on Sep 23, 2010 at 20:12 UTC
    It seems like this may be an XY Problem, but you can accomplish your goal simply using eval because your string contains valid Perl syntax. Be aware that if this string comes from a potentially untrusted source, using eval will hand over the keys to the kingdom.

    my $string = "1,5,7..10,15,17..19,22"; my @array = eval($string); print join ", ", @array;

    On a side note, please wrap code, input and output in <code> tags - it makes your life and our lives easier. See Writeup Formatting Tips.

Re: Converting String Containing Ranges to Array
by Corion (Patriarch) on Sep 23, 2010 at 20:15 UTC

    eval?

    perl -wle "print for eval shift" 1,5,7..10,15,17..19,22

    There also is a node somewhere on here, where this issue is discussed further, but I can't find it currently.

Re: Converting String Containing Ranges to Array
by BrowserUk (Patriarch) on Sep 23, 2010 at 20:24 UTC

    my @a; push @a, /\.\./ ? do{ my($lo,$hi) = split'\.\.'; $lo..$hi} : $_ for split',', $string; print @a;; ##or my @a = map{ /\.\./ ? do{ my( $lo,$hi ) = split '\.\.'; $lo .. $hi } : $_ } split ',', $string; print @a;;

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Converting String Containing Ranges to Array
by toolic (Bishop) on Sep 23, 2010 at 20:34 UTC
    Set::IntSpan
    use strict; use warnings; use Set::IntSpan; my $s = "1,5,7..10,15,17..19,22"; $s =~ s/\.\./-/g; my $set = Set::IntSpan->new($s); my @elements = $set->elements(); print Dumper(\@elements); __END__ $VAR1 = [ 1, 5, 7, 8, 9, 10, 15, 17, 18, 19, 22 ];
Re: Converting String Containing Ranges to Array
by Anonymous Monk on Sep 23, 2010 at 21:26 UTC
    perl -lE '@f=map { ($l,$h)=split/\.\./;$h//=$l;($l..$h)} split/,/,$ARG +V[0]; for ($i=0;$i<=$#f;$i++){print "$i -> $f[$i]"}' 1,5,7..10,15,17. +.19,22 0 -> 1 1 -> 5 2 -> 7 3 -> 8 4 -> 9 5 -> 10 6 -> 15 7 -> 17 8 -> 18 9 -> 19 10 -> 22