$s = "1-6,27,105-170,512,670-675";; @ranges = map{ my( $lo, $hi ) = split '-', $_; $hi //= $lo; die 'Bad input' if $lo > $hi; [ $lo, $hi ] } split ',', $s;; print "@$_" for @ranges;; 1 6 27 27 105 170 512 512 670 675 #### qr[ ^\s* ## from the start of the string, skip whitespace (if any) (?: \d+ - \d+ ) ## then grab (at least one) pair of numbers separated by '-' (?: ## a group \s* , \s* ### a comma, optionally preceded or followed by whitespace \d+ - \d+ ### and another pair of numbers separated by '-' )* ## zero or more times \s*$ ## to the end of string, optionally skipping whitespace if any ]x