我有一个文件,其中包含如下所示的数字列表:
10^-92
2 10^-14
10^-105
3 10^-20
进一步解释10^-92
基本上是1E-92
而2 10^-14
是2E^-14
。
有没有一种紧凑的方法将上述文件中的数字转换为Perl号码?最后,我想用数字对这些数字进行排序。
答案 0 :(得分:5)
如果所有数字都需要相同的转换成为Perl的数字,为什么不使用正则表达式替换:
use 5.010;
my @nums = ('10^-92', '2 10^-14', '10^-105', '3 10^-20');
s{ (\d*) \s* 10\^ }{ ($1 || 1) . 'e' }xe for @nums;
say "@nums"; # 1e-92 2e-14 1e-105 3e-20
答案 1 :(得分:1)
如果你想要一个Perl号码,只需直接找到没有eval的号码。存储您提取的数字部分,并以缓存键排序方式使用它们:
use 5.010;
while( <DATA> )
{
chomp;
m/
(?:
(?<coefficient> \d+ (?:\.\d+)? )
\s+
)?
(?<base> (\d+) )
\^
(?<exponent> -?\d+ )
/x;
push @numbers,
[ ( $+{coefficient} // 1 ), $+{exponent}, $_ ];
}
my @sorted = sort {
$a->[1] <=> $b->[1]
||
$a->[0] <=> $b->[0]
} @numbers;
foreach my $number ( @sorted )
{
print "$number->[-1]\n";
}
__DATA__
10^-92
2 10^-14
10^-105
3 10^-20
你可以把它归结为Schwartzian变换:
use 5.010;
print
map {
$_->[-1]
}
sort {
$a->[1] <=> $b->[1]
||
$a->[0] <=> $b->[0]
}
map {
m/
(?:(?<c> \d+ (?:\.\d+)? ) \s+ )? # coefficient
(?<b> (\d+) ) # base
\^
(?<e> -?\d+ ) # exponent
/x;
[ ( $+{c} // 1 ), $+{e}, $_ ];
} <DATA>;
__DATA__
10^-92
2 10^-14
10^-105
3 10^-20
答案 2 :(得分:0)
$ perl -ne 's/ /*/;s/\^/E/;print "\n".eval $_' file
2e-13
1e-91
2e-13
1e-104
3e-19