sub consecutive { local $_ = join " ", sort { $a <=> $b } grep !/\D/, @_; s[ (\d+ \s*) ( (??{$++1}) \s* )* ] "$1 => ${\($+-$1)},"gx; return eval "{ $_ }"; } use Data::Dumper; print Dumper(consecutive qw(20 2 3 4 5 6 7 23 19 17 25 30 11 12 22 21 68 103829 24 18));