use warnings; use strict; my @examples = ( [ 'Rack1-Unit2', 'Rack3-Unit1', 'Rack1-Unit1' ], [ 'R2U3', 'R1U4', 'R10U1', 'R1U1' ], [ 'R2-U3', 'R1-U4', 'R10-U1', 'R1-U1' ], ); my $rackre = qr/R(?:ack)?(\d+)/i; my $unitre = qr/U(?:nit)?(\d+)/i; my %orderings = ( rackfirst => sub { ($a =~ $rackre)[0] <=> ($b =~ $rackre)[0] or ($a =~ $unitre)[0] <=> ($b =~ $unitre)[0] }, unitfirst => sub { ($a =~ $unitre)[0] <=> ($b =~ $unitre)[0] or ($a =~ $rackre)[0] <=> ($b =~ $rackre)[0] }, ); for my $ex (@examples) { print "Input: @$ex\n"; for my $o (sort keys %orderings) { my @sorted = sort {&{$orderings{$o}}} @$ex; print "$o: @sorted\n"; } } __END__ Input: Rack1-Unit2 Rack3-Unit1 Rack1-Unit1 rackfirst: Rack1-Unit1 Rack1-Unit2 Rack3-Unit1 unitfirst: Rack1-Unit1 Rack3-Unit1 Rack1-Unit2 Input: R2U3 R1U4 R10U1 R1U1 rackfirst: R1U1 R1U4 R2U3 R10U1 unitfirst: R1U1 R10U1 R2U3 R1U4 Input: R2-U3 R1-U4 R10-U1 R1-U1 rackfirst: R1-U1 R1-U4 R2-U3 R10-U1 unitfirst: R1-U1 R10-U1 R2-U3 R1-U4