Is there a function that groups numbers (thousands)?
Hidden somewhere in a (small) module is a function that does this for me:
my $var = 23654325432;
$var = reverse $var;
$var =~ s/\d{3}\K(?=\d+)/_/g;
$var = reverse $var;
I like Number :: Format , but it didn't pass all tests on windows.
use Number::Format;
my $nf = new Number::Format(
-thousands_sep => ',',
-decimal_point => '.',
);
my $formatted = $nf->format_number( 23142153 );
source to share
The fastest method is in perlfaq
( perldoc -q commas
):
sub commify {
local $_ = shift;
1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
return $_;
}
Of course, I just came up with a feature that outperforms it by ~ 70%.
use constant THOU_SEP => ',';
use English qw<@LAST_MATCH_START @LAST_MATCH_END>;
sub ss_commify {
my $s = shift;
return $s unless $s =~ m/\d{4,}/;
my ( $f, $p ) = ( $LAST_MATCH_START[0], $LAST_MATCH_END[0] );
my $ts = THOU_SEP;
# |-- That is, replace a *0-length* substring at $p with the
# v thousand separator
substr( $s, $p, 0, $ts ) while ( $p -= 3 ) > $f;
return $s;
}
And it works with whatever text you have in the front or back. The FAQ version just works backwards (admittedly a numeric value in Perl).
The idea is that you want to work with the regex once, and then just use Perl's elastic string implementation to do the surface work. The substitution for each of these appears to be slightly higher than necessary.
source to share
I use
$num =~ s/(\d) (?= (?:\d{3})+ \b )/$1,/gx;
which just adds a comma after each digit followed by multiple digits.
If you want to use a function:
sub commify {
(my $num = $_[0]) =~ s/(\d) (?= (?:\d{3})+ \b )/$1,/gx;
$num;
}
print commify(10 ** $_), "\n" for 1 .. 14;
OUTPUT
10 100 1,000 10,000 100,000 1,000,000 10,000,000 100,000,000 1,000,000,000 10,000,000,000 100,000,000,000 1,000,000,000,000 10,000,000,000,000 100,000,000,000,000
source to share