will help. Since then, I have wrapped it up in a module:
package String::Numerify;
### Convert string to number with prefix support
use warnings;
use strict;
BEGIN
{
require Exporter;
*import = \&Exporter::import; # just inherit import() only
our $VERSION = 1.001;
our @EXPORT_OK = qw(&num);
}
# prefix to exponent value conversion table
my %prefix2exp = (
Y => +24, # yotta
Z => +21, # zetta
E => +18, # exa
e => +18, # exa
P => +15, # peta
T => +12, # terra
t => +12, # terra
G => +9, # giga
g => +9, # giga
X => +6, # mega
M => +6, # mega
K => +3, # kilo
k => +3, # kilo
"" => 0, # default is no prefix
m => -3, # milli
u => -6, # micro
U => -6, # micro
n => -9, # nano
N => -9, # nano
p => -12, # pico
f => -15, # femto
F => -15, # femto
a => -18, # atto
z => -21, # zepto
y => -24, # yocto
);
# define regexes to match decimal-point number
my $dp_regex1 = qr/(\d+[.]?\d*)/;
my $dp_regex2 = qr/(\d*[.]?\d+)/;
# examples: " -+--.13e4u99..99.0" => -0.0013 , "+-- 123.mA" => 0.123
sub num {
my ($numstr) = @_;
# string must contain digit
if ($numstr =~ /\d/)
{
my ($sign, $exponent, $prefix) = ("+", 0, "");
# does first digit appear before or after potential decimal po
+int?
my $dp_regex = ($numstr =~ /^[^.]*\d/s ? $dp_regex1 : $dp_rege
+x2);
# clean string for best chance at numerification
$numstr =~ s/^.*?([+-]?)$dp_regex(?:[eE]([+-]?\d+))?([YZEePT
+tGgXMKkmuUnNpfFazy])?.*/$2/s;
$sign = $1 if $1;
$exponent = $3 if $3;
$prefix = $4 if $4;
# convert prefixes -- example: ".16E2m" => ".16e-1" => 0.016
if ($exponent || $prefix)
{
$exponent += $prefix2exp{$prefix};
$numstr .= "e".$exponent;
}
# numerify string according to nearest sign
{
no warnings 'numeric';
$numstr = -+-$numstr; # high-precedence nu
+merifier
$numstr = -$numstr if $sign eq "-"; # negative if last s
+ign is "-"
}
}
else
{
$numstr = undef;
}
return $numstr;
}
'String::Numerify';