#!/usr/bin/env perl use 5.010; use warnings; use strict; say <<'EOF'; .,-;:!?"'`_#$%&*+/|=@\^~()<>[]{}0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz intended sequence !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ natural ASCII sequence EOF my @list = qw{ "Hello" Abel (hello) {adieu} @adieu [goodbye] Charlie ^Charlie ~Adieu zebra 21708 baker . - ; : ! ? " ' ` _ }; my @sorted_list = sort { # for each $a:$b comparison, transliterate $a and $b into temp vars $x and $y my ($x,$y) = map { my $z = $_ =~ tr / .,-;:!?"'`_#$%&*+\/|=@\\^~()<>[]{}0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz / !"#$%&'()*+,-.\/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ /r; # don't smash the original $a and $b, instead assign to $z #printf "%-10s -> %-10s\n", $_, $z; $z; } ($a,$b); # transliterate $a and $b into $x and $y for sorting show_compare($a, $b, $x, $y); $x cmp $y } @list; say "\nSorted list"; say for @sorted_list; sub show_compare { my ($a, $b, $x, $y) = @_; printf "%-10s %-10s %s %-10s %-10s\n", $a, $x, (qw/< = >/)[1+($x cmp $y)], $b, $y; }