Is there a function which does grouping numbers (thousand)?

谁说我不能喝 提交于 2019-12-06 00:09:20
JRFerguson

Look at perl5i. It has commify and group_digits methods.

The fastest method is in the 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 function that beats this one 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 front or back. The FAQ version just works with text in back (admittedly a numeric value in Perl).

The idea is find what you want to work on with the regex once and then simply use Perl's elastic string implementation to do the perfunctory work. A substitution for each of these seems to be a bit more overhead than necessary.

I use

$num =~ s/(\d) (?= (?:\d{3})+ \b )/$1,/gx;

which just adds a comma after every digit that is followed by a multiple of three digits.

If you'd like a function instead:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!