my %data; for my $k (keys %form) { # assumes all the keys are non-numbers followed by numbers my ($letters, $numbers) = $k =~ /(\D+)(\d+)/; $data{$numbers}{$letter} = $form{$k}; } #### # UPDATE (fixed indices!) my @sorted_keys = map { $_->[0] } sort { $a->[2] <=> $b->[2] or $a->[1] cmp $b->[1] } map { [$_, /(\D+)(\d+)/] } keys %form;