KB
1024字節。基洛作爲前綴通常意味着的東西,因爲它意味着1000*1000
,1024*1024
和1000*1024
不是1024
問題更糟與MB
得到1000。
1.44 MB軟盤實際上保存1.44 * 1000 * 1024
。
唯一真正的出路就是使用新的KiB
(Kibibyte)表示1024字節。
你實現它也順便有,你不能使用8.4Gi
意味着8.4 * 1024 * 1024
的限制。爲了消除該限制,我使用中的$RE{num}{real}
而不是\d+
。
其他一些答案通過寫出所有可能的匹配來強化匹配。這可能非常乏味,更不用說容易出錯。爲了解決這個問題,我使用了%multiplier
的鍵來生成正則表達式。這意味着如果您添加或刪除%multiplier
中的元素,則無需手動修改正則表達式。
use strict;
use warnings;
use Regexp::Common;
my %multiplier;
my $multiplier_match;
{
# populate %multiplier
my %exponent = (
K => 1, # Kilo Kibi
M => 2, # Mega Mebi
G => 3, # Giga Gibi
T => 4, # Tera Tebi
P => 5, # Peta Pebi
E => 6, # Exa Exbi
Z => 7, # Zetta Zebi
Y => 8, # Yotta Yobi
);
while(my ($str,$exp) = each %exponent){
@multiplier{ $str, "${str}B" } = (1000 ** $exp) x2; # K KB
@multiplier{ "${str}i", "${str}iB" } = (1024 ** $exp) x2; # Ki KiB
}
# %multiplier now holds 32 pairs (8*4)
# build $multiplier_match
local $" #" # fix broken highlighting
= '|';
my @keys = keys %multiplier;
$multiplier_match = qr(@keys);
}
sub remove_multiplier{
die unless @_ == 1;
local ($_) = @_;
# s/^($RE{num}{real})($multiplier_match)$/ $1 * $multiplier{$2} /e;
if(/^($RE{num}{real})($multiplier_match)$/){
return $1 * $multiplier{$2};
}
return $_;
}
如果你絕對需要1K來表示1024,那麼你只需要改變一行。
# @multiplier{ $str, "${str}B" } = (1000 ** $exp) x2; # K KB
@multiplier{ $str, "${str}B" } = (1024 ** $exp) x2; # K KB
需要注意的是,因爲我用$RE{num}{real}
從Regexp::Common它還將與5.3e1Ki
工作。
首先,您的代碼不會按原樣運行。你在每個語句後加上'*',所以KB | MB | GB部分是可選的(0或更多)。你確定這是你想要的嗎? – Konerak 2012-02-06 16:42:01