2

I'd like to convert a sting of the form 1,2,25-27,4,8,14,7-10 into a list of the actual values: 1,2,4,7,8,9,10,14,25,26,27.

I've searched and found nothing that does this sort of expansion. Anyone aware of way to do this easily?

RobEarl
  • 7,862
  • 6
  • 35
  • 50
SecondGear
  • 1,093
  • 1
  • 12
  • 18

2 Answers2

5
my $s = "1,2,25-27,4,8,14,7-10";
my %seen;
my @arr =
  sort { $a <=> $b }
  grep { !$seen{$_}++ }
  map { 
    my @r = split /-/; 
    @r>1 ? ($r[0] .. $r[1]) : @r;
  }
  split /,/, $s;

print "@arr\n";

output

1 2 4 7 8 9 10 14 25 26 27
mpapec
  • 50,217
  • 8
  • 67
  • 127
  • I'll write explanation if you need it – mpapec Oct 11 '13 at 15:05
  • 2
    The perl is strong with this one! That's elegant and exactly what I was looking for. Thanks you very much. While I could not have written that on my own, I can follow what it's doing. – SecondGear Oct 11 '13 at 15:18
2

Another way to do this quickly is by using the string version of eval. But you have to keep in mind that the use of eval have some security implication so you better sanitize any string before passing it to eval.

use strict;
use warnings;

my $string = "1,2,25-27,4,8,14,7-10";

$string =~ s/-/../g;

my @list = sort {$a <=> $b} keys { map {$_, 1} eval $string };

print "@list\n";  

#output
1 2 4 7 8 9 10 14 25 26 27   
edi_allen
  • 1,878
  • 1
  • 11
  • 8