define get_num use $lst # "-22" split by "-" is [ "", "22" ] so check if # first list item is "" -> a negative number $lst 0 get "" = if # negative number # # convert str to integer and multiply by -1 -1 $lst 1 get 0 prefer * $lst shift $lst shift drop drop else # positive number $lst 0 get 0 prefer $lst shift drop define range_expand use $rng [ ] as $res $rng "," split each as $r $r m/^(-?\d+)-(-?\d+)$/ TRUE = if $r s/-/g as $parts $parts get_num as $from $parts get_num as $to # int list to str list, then joined by "," group $from $to 1 range each "" prefer list "," join $res push # range doesn't include the $to, so add to end of generated range $to "%d" $res push else $r $res push $res "," join print "\n" print '-6,-3--1,3-5,7-11,14,15,17-20' range_expand