2017-08-28 259 views
-1

如果我有一個字符串具有以下格式的數組:如何使用字母數字字符串中的數字進行排序?

[1900] ABC 15 

我如何用perl sort,這樣它按第一個數字,然後由第二數組排序?

perldoc sort這個例子似乎是相關的:

my @new = sort { 
    ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0] 
         || 
       fc($a) cmp fc($b) 
} @old; 
+0

當你說Perl時,你應該在上下文中顯示一些代碼。這個'[1900] ABC 15'沒有任何意義。 – sln

+0

我想你會需要定義你自己的排序子程序,然後檢查你想要比較的字符串部分。你可能會追加第二個數字到第一個來獲得一個數字(190015)進行比較。 –

+0

我沒有讓你失望。 – sln

回答

4

從文檔拉到這個例子給出了這個概念:通過一個標準進行比較,如果他們被發現由cmp<=>equality operators,然後返回0等於,請進入下一個標準。

所以在這種情況下比較由字符串中的第一個數字,然後由第二個。

use warnings; 
use strict; 
use feature 'say'; 

my @old = ('[1900] ABC 15', '[1900] ABC 5', '[1800] ABC 20'); 

my @new = sort { 
    my ($a1, $a2) = $a =~ /([0-9]+)/g; 
    my ($b1, $b2) = $b =~ /([0-9]+)/g; 

    $a1 <=> $b1 or $a2 <=> $b2; 

} @old; 

say for @new; 

打印

 
[1800] ABC 20 
[1900] ABC 5 
[1900] ABC 15 

如果排序需要在從大到小的順序互換a和比較b

這可以通過預先計算整個列表的正則表達式來更有效地完成,以便在每次比較元素時不會重新執行它們。文檔示例的延續顯示了這一點,最後一個版本是Schwartzian transform

但請記住,這種優化只適用於較大的數據集,而對於簡單的計算它們的開銷也很重要。 以上基本sort一般就足夠了。


注意  一個[0-9]\d匹配而且還有其它字符(360更有人告訴我),它是支持Unicode。 /a字符集修改器的情況並非如此,自5.14起可用。但是,這具有的效果比限制\d更廣泛。在perlre中搜索/a。 因此,我在這裏使用了0-9來進行精度和小的效率測量,並且不限制\s,\w和POSIX字符類。

+0

使用'/ a'修飾符,'\ d'只匹配'[0-9]',請參閱:http://perldoc.perl.org/perlretut.html – Toto

+0

@Toto謝謝,這就是我所指的通過「_without modifiers_」。從那時起,我不想詳細介紹'/ aa',這是一個附註。但最好說出來,謝謝。 – zdim

+0

@Toto我沒有把它添加到文本中,感謝評論。 – zdim

0

我寫了一個函數做了這種排序前一段時間。 它使用字符串中的所有數字進行數字排序。 我不在乎表現,對不起。希望能幫助到你。

sub num_sort($$) { 
    my ($a,$b)[email protected]_; 
    my @sa=reverse grep /./s, split /(\d+)/,$a; 
    my @sb=reverse grep /./s, split /(\d+)/,$b; 
    for (;;) { 
    last if [email protected] || [email protected]; 
    my $ea=pop @sa; 
    my $eb=pop @sb; 
    my $rc= ($ea <=> $eb) || ($ea cmp $eb); 
    if ($rc) { 
     return $rc; 
    } 
    } 
    return @sa <=> @sb; 
} 
相關問題