2014-04-09 3 views
0

나는 같은 해시 키가 있습니다정렬 문자열의 해시와 숫자

FastEthernet1 
GigabitEthernet1/1 
GigabitEthernet1/10 
GigabitEthernet1/2 
GigabitEthernet1/20 

을하지만 1-48에서 그들을 가지고 있고 또한이 2/1 - 48 등 ​​

foreach my $i (sort keys %intconfigs) 것 위와 똑같이 인쇄하십시오.

FastEthernet1 
GigabitEthernet1/1 
GigabitEthernet1/2 
GigabitEthernet1/10 
GigabitEthernet1/20 

내가이 foreach my $i (sort { $a <=> $b } keys %intconfigs)을 시도했지만 그에게 오는 :

는하지만 내가 원하는 것은

GigabitEthernet1/2 
GigabitEthernet1/10 
GigabitEthernet1/20 
GigabitEthernet1/1 
FastEthernet1 

제대로이를 정렬하는 방법을 잘하지 않습니다. 어떤 도움을 주시면 감사하겠습니다. 당신이 적절하게 각 섹션을 정렬 할 수 있도록

답변

2

당신은 여부 알파 또는 숫자 비교로, 부분으로 값을 깰 수 :

my @keys = qw(
    FastEthernet1 
    GigabitEthernet1/1 
    GigabitEthernet1/10 
    GigabitEthernet1/2 
    GigabitEthernet1/20 
); 

my @sorted = sort { 
    my ($a_name, $a_num1, $a_num2) = $a =~ m{(.*?)(\d+)(?:/(\d+))?}; 
    my ($b_name, $b_num1, $b_num2) = $b =~ m{(.*?)(\d+)(?:/(\d+))?}; 
    $a_name cmp $b_name or $a_num1 <=> $b_num1 or $a_num2 <=> $b_num2; 
} @keys; 

print "$_\n" for @sorted; 

또는 사용하여 좀 더 고급 정규식 기술 :

my @sorted = sort { 
    local ($a, $b) = map { m{(?<name>\D+) (?<num1>\d+) (?:/(?<num2>\d+))?}x ? {%+} : die "Can't parse: $_" } ($a, $b); 
    $a->{name} cmp $b->{name} or $a->{num1} <=> $b->{num1} or $a->{num2} <=> $b->{num2} 
} @keys; 

또는 모듈 Sort::Key::Natural을 사용하여 숫자 부분을 숫자순으로 자동 정렬 할 수 있습니다.

use Sort::Key::Natural qw(natsort); 

my @sorted = natsort @keys; 

print "$_\n" for @sorted; 

두 가지 방법 출력 :

FastEthernet1 
GigabitEthernet1/1 
GigabitEthernet1/2 
GigabitEthernet1/10 
GigabitEthernet1/20 
+0

감사합니다. 이 두 가지 모두 훌륭한 해답입니다. – MysticRyuujin

+0

@MysticRyuujin 귀하의 환영입니다. – Miller

+0

nsort는 정규식에 대해 걱정할 필요없이 GigabitEthernet1/0/12 및 GigabitEthernet1/1/1과 같은 제품과 함께 작동하는 것으로 보입니다. – MysticRyuujin

0

자리의 긴 시리즈에 0 패딩 포함 된 모든 숫자에 의해 형성되는 문자열의 변화에 ​​문자열을 정렬하는 것입니다 귀하의 경우 일하는 것이 또 다른 쉬운 일을, , 그래서 그들은 정확하게 정렬 문자열.

use List::UtilsBy qw(sort_by); 

my @ifaces = sort_by { s/(\d+)/sprintf "%09d", $1/eg; $_ } qw(
    FastEthernet1 
    GigabitEthernet1/1 
    GigabitEthernet1/10 
    GigabitEthernet1/2 
    GigabitEthernet1/20 
); 

say for @ifaces 

실제로 필요한 순서로 인쇄합니다.

이 경우에는 9 자리보다 긴 숫자 시퀀스 또는 부동 소수점 숫자가 포함 된 문자열의 경우와 같이 아주 일반적인 해결책은 아닙니다.