2013-08-05 39 views
1

我必須處理零件號,什麼是字母數字字符串。零件號碼長度爲14個字符,但零件結構(s.c.高級零件)號碼較短。在元數據轉換中,上級零件號需要擴展到14個字符的全長,並帶有零。在Perl中擴展帶尾隨零的字符串

我想出了以下解決方案

my $number = "M30SA0000002"; # same upper level part number 
my $len = 14; 

if (length($number) < $len) { 
    print "Number [$number] is smaller, length (" . length ($number) . ")\n"; 
    $number = sprintf("%-${len}s", $number); 
    $number =~ tr/ /0/; 
} 
print "\New number [$number], length (" . length ($number) . ")\n" 

這裏的輸出

Number [M30SA0000002] is smaller, length (12) 
New number [M30SA000000200], length (14) 

雖然這會產生理想的結果,這填補有點尷尬的2線執行這個簡單的任務。有沒有辦法在一行中做到這一點?可惜sprintf沒有提供一種擴展字符串的方式來添加任何結尾字符。

生產環境在Windows Server計算機上運行,​​Perl版本爲5.14.2.1,沒有CPAN模塊,只有可用的核心模塊。

編輯: 我已經基準4個解決方案

use Benchmark qw(:all); 
timethese(10000000, { 
      'While' => sub { my $number = "M30SA0000002"; $number .= '0' while 14 > length $number; }, 
      'Repeat' => sub { my $number = "M30SA0000002"; $number .= '0' x (14 - length $number); }, 
      'Substring' => sub { my $number = "M30SA0000002"; $number = substr($number . "0" x 14, 0, 14); }, 
      'Sprintf' => sub { my $number = "M30SA0000002"; $number = sprintf("%-14s", $number); $number =~ tr/ /0/; }, 
}); 

這裏的結果:

Benchmark: timing 10000000 iterations of Repeat, Sprintf, Substring, While... 
    Repeat: 2 wallclock secs (1.65 usr + 0.00 sys = 1.65 CPU) @ 6045949.21/s (n=10000000) 
    Sprintf: 3 wallclock secs (3.90 usr + 0.00 sys = 3.90 CPU) @ 2564102.56/s (n=10000000) 
Substring: 3 wallclock secs (2.78 usr + 0.00 sys = 2.78 CPU) @ 3602305.48/s (n=10000000) 
    While: 2 wallclock secs (2.81 usr + 0.00 sys = 2.81 CPU) @ 3561253.56/s (n=10000000) 

重複的解決方案似乎是最快的這一切。

+1

[String :: Formatter](http://p3rl.org/String::Formatter),當你想擴展'sprintf'並意識到你不能。 – daxim

+0

String :: Formatter不是核心Perl模塊。我不能使用CPAN模塊,或者至少我需要證明它的用法,但我必須經歷非常長的批准過程。所以我肯定會跳過這一個。 – edufinn

+0

是什麼讓隨機代碼離開Web(堆棧溢出)好,但沒有(CPAN)千倍測試,其他地方有效地使用? – daxim

回答

3

你可以用一個 「附加」 分配一起使用while修改:

$number .= '0' while 14 > length $number; 

或做一些數學和使用重複操作符(感謝@loldop):

$number .= '0' x (14 - length $number); 
+2

'$ number。='0'x(14 - 長度$數字)'? – gaussblurinc

+0

@loldop:很好。作爲可能性添加。 – choroba

+0

我們的程序已經有很多循環。關於提供解決方案性能,您可以說些什麼 – edufinn

2

一步法解決方案是附加很多0's,並砍掉你不需要的那些:

$number = substr($number . "0" x 14, 0, 14);