Прежде всего, ваша подпрограмма сортировки не работает с передаваемыми вами значениями. Это должно быть что-то вроде
sub num_last {
my ($num_a, $num_b);
my ($a,$b) = @_;
....
}
Чем вы действительно получаете только первую цифру в строке , если строка начинается с цифры . На всякий случай лучше добавить пропуск всех ведущих пробелов.
($num_a) = $a =~ /^\s*(\d+)/;
($num_b) = $b =~ /^\s*(\d+)/;
\d+
эквивалентно [0-9]+
, но на два знака короче :). Сила скобок list context
, поэтому $num_a
и $num_b
получают содержимое первой соответствующей группы: (\d+)
.
Чем вам не нужен <=>
оператор, так как $num_a
и $num_b
должны быть строками, чтобы вы могли упростить ваше условие до:
if (!$num_a)
return -1;
if (!$num_b)
return 1;
return $a cmp $b;
Не уверен, но это может быть так же просто, как return $a cmp $b
, но я не уверен, что пустая переменная по строке меньше, чем непустая строка и нет perl в кончиках пальцев. Итак, финальная функция num_last:
sub num_last{
my ($num_a, $num_b);
my ($a,$b) = @_;
($num_a) = $a =~ /^\s*(\d+)/;
($num_b) = $b =~ /^\s*(\d+)/;
if (!$num_a)
return -1;
if (!$num_b)
return 1;
return $a cmp $b;
}
Если вам нужна обратная сортировка, просто замените my ($a,$b) = @_;
на my ($b,$a) = @_;
И я написал это без помощи компилятора, так что в нем могут быть незначительные ошибки.