my @a = qw/1 2 2.2 2.13 2.1.7 3.4a 10.4a.3b.8/; my @sortables = map { [grep /[^\.]/, split/([\.a-z])/, $_] } @a; print join "\n", map join(' ', @{$_}), @sortables; #### my @list = qw/1 10.4a.3b.8 2.2 2 2.13 3.4a 2.1.7 /; print join "\n", sort compare @list; sub compare { my @a = grep /[^\.]/, split/([\.a-z])/, $a; my @b = grep /[^\.]/, split/([\.a-z])/, $b; { my ($c, $d) = (shift @a, shift @b); (!defined $c and defined $d) and return -1; ( defined $c and !defined $d) and return 1; (!defined $c and !defined $d) and return 0; ($c > $d) and return 1; ($c < $d) and return -1; redo; } } #### my @list = qw/1 10.4a.3b.8 2.2 2 2.13 3.4a 2.1.7 /; my @cache = map { [grep /[^\.]/, split/([\.a-z])/, $_] } @list; print join("\n", map("@$_", sort compare @cache)); sub compare { my @a = @$a; my @b = @$b; { my ($c, $d) = (shift @a, shift @b); (!defined $c and defined $d) and return -1; ( defined $c and !defined $d) and return 1; (!defined $c and !defined $d) and return 0; ($c > $d) and return 1; ($c < $d) and return -1; redo; } }