Synopsis
I deal with a lot of names that look like “somedumbserver2” and “somedumbserver15”. Using Perl’s default sort, “somedumbserver2” comes before “somedumbserver15” because the character “2” is greater than the character “1”, and that’s where the sort stops. This sort, “snsort” or “string-number sort”, is a little wiser, and all else being equal compares the number “2” to the number “15”, and properly orders it. It’s also safe to use if some strings don’t conform to this pattern.
I wrote this to be a Vmethod to list objects in Template Toolkit, so I kept the surrounding code intact in case anyone wants to use it as-is, but “sub sns” can be taken out and put in any Perl program, and used in conjunction with the Perl “sort” function.
Code
$Template::Stash::LIST_OPS->{ snsort } = sub {        my $list = shift;        return sort sns @$list;               sub sns {                my @aparts=$a =~ /^(\D+)(\d+)$/;                my @bparts=$b =~ /^(\D+)(\d+)$/;                               return $a cmp $b unless @aparts and @bparts; # Safety                return $aparts[0] cmp $bparts[0] unless $aparts[0] eq $bparts[0];                return $aparts[1] <=> $bparts[1];        } };
I was dealing with this issue as well, and couldn’t figure out a good solution for what at first seemed like an easy problem. Thanks for posting your algorithm, its exactly what I needed!