@sorted = sort by_num_then_letter @unsorted; sub by_num_then_letter { my $a_region = lc ($a->region_name); my $b_region = lc ($b->region_name); my $a_non_digit = ($a_region =~ /\D/); my $b_non_digit = ($b_region =~ /\D/); if ($a_non_digit and $b_non_digit) { $a_region cmp $b_region } elsif (!$a_non_digit and !$b_non_digit) { $a_region <=> $b_region } elsif ($a_non_digit) #digit only thing is always less than { 1; # b > a (reverse 1 and -1 if I got this wrong) } else { -1; # b