package Sort::Key::Natural; our $VERSION = '0.03'; require Exporter; our @ISA = qw( Exporter ); our @EXPORT_OK = qw( natkeysort natkeysort_inplace rnatkeysort rnatkeysort_inplace mkkey_natural natsort rnatsort natsort_inplace rnatsort_inplace ); sub mkkey_natural { my $nat = @_ ? shift : $_; my @parts = $nat =~ /\d+|[[:alpha:]]+/g; for (@parts) { if (/^\d/) { s/^0+//; my $len = length; my $nines = int ($len / 9); my $rest = $len - 9 * $nines; $_ = ('9' x $nines) . $rest . $_; } } return join("\0", @parts); } use Sort::Key::Register natural => \&mkkey_natural, 'string'; use Sort::Key::Register nat => \&mkkey_natural, 'string'; use Sort::Key::Maker natkeysort => 'nat'; use Sort::Key::Maker rnatkeysort => '-nat'; use Sort::Key::Maker natsort => \&mkkey_natural, 'str'; use Sort::Key::Maker rnatsort => \&mkkey_natural, '-str'; 1; =head1 NAME Sort::Key::Natural - fast natural sorting =head1 SYNOPSIS use Sort::Key::Natural qw(natsort); my @data = qw(foo1 foo23 foo6 bar12 bar1 foo bar2 bar-45 foomatic b-a-r-45); my @sorted = natsort @data; print "@sorted\n"; # prints: # b-a-r-45 bar1 bar2 bar12 bar-45 foo foo1 foo6 foo23 foomatic use Sort::Key::Natural qw(natkeysort); my @objects = (...); my @sorted = natkeysort { $_->get_id } @objects; =head1 DESCRIPTION This module extends the L family of modules to support natural sorting. Under natural sorting, strings are splitted at word and number boundaries, and the resulting substrings are compared as follows: =over 4 =item * numeric substrings are compared numerically =item * alphabetic substrings are compared lexically =item * numeric substrings come always before alphabetic substrings =back Spaces, symbols and non-printable characters are only considered for splitting the string into its parts but not for sorting. For instance C is broken in three substrings C, C and C<42> and after that the dashes are ignored. Also, once this module is loaded, the new type C (or C) will be available from L. For instance: use Sort::Key::Natural; use Sort::Key::Maker i_rnat_keysort => qw(integer -natural); creates a multikey sorter C accepting two keys, the first to be compared as an integer and the second in natural descending order. =head2 FUNCTIONS the functions that can be imported from this module are: =over 4 =item natsort @data returns the elements of C<@data> sorted in natural order. =item rnatsort @data returns the elements of C<@data> sorted in natural descending order. =item natkeysort { CALC_KEY($_) } @data returns the elements on C<@array> naturally sorted by the keys resulting from applying them C. =item rnatkeysort { CALC_KEY($_) } @data is similar to C but sorts the elements in descending order. =item natsort_inplace @data =item rnatsort_inplace @data =item natkeysort_inplace { CALC_KEY($_) } @data =item rnatkeysort_inplace { CALC_KEY($_) } @data these functions are similar respectively to C, C, C and C, but they sort the array C<@data> in place. =item mkkey_natural $key transforms key C<$key> in a way that when sorted with L keysort results in a natural sort. If the argument C<$key> is not provided it defaults to C<$_> =back =head1 SEE ALSO L, L. Other module providing similar functionality is L. =head1 COPYRIGHT AND LICENSE Copyright (C) 2006 by Salvador FandiEo, Esfandino@yahoo.comE. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available. =cut