Sorting by function is really easy. The function has to return -1, 0 or 1 depending if $a and $b are before or after. (As noted in comments - it can be any positive or negative value - the key point is whether the elements are before or after each other).
$a and $b are 'special' variables used specifically for perl and sorting. They therefore don't need to be declared, and are a really bad idea to use for other stuff in your code. But then, who uses single letter vars anyway?
So with your values:
#!/usr/bin/env perl
use strict;
use warnings;
sub custom_sort {
my ( $a1, $a2 ) = ( $a =~ m/(\d+)/g ); #extract the numeric elements
my ( $b1, $b2 ) = ( $b =~ m/(\d+)/g );
return ( $a1 <=> $b1 #return the result of this comparison
|| $a2 <=> $b2 ); #unless it's zero, then we return the result of this.
}
my @list = <DATA>;
print sort custom_sort @list;
__DATA__
Expt5_Expt12
Expt5_Expt1
Expt12_Expt2
Expt11_Expt8
Expt1_Expt2
Expt10_Expt1
Expt10_Expt4
Expt11_Expt1
You can make this more concise, but the essence is this:
- extract the first and second values.
- Then use the
|| operator - so that if $a1 <=> $b1 is zero, it evaluates the second part of the expression.
<=> is a 'less than, equal to, greater than' operator which returns -1, 0 or 1 based on numeric comparison. For strings you can use cmp to do the same thing.
(You can print these if you wish to debug how this sort is 'working' for each comparison, which is really handy if you're doing something complicated)