怎样用printf实现“999,999”这样的输出?

怎样用printf实现“999,999”这样的输出?

File System Usage

File_System         Mount_Point         Total_Space         Free_Space         Used_Rate
/dev/dsk/c0d0s0         /         7385 M         2438 M         67 %
swap         /tmp         459 M         455 M         1 %
/dev/dsk/c0d1s2         /data         40311 M         24993 M         38 %

我想把24993这种数字变成24,993这各格式,应该用什么样的printf格式啊?
sub commify {
    local $_  = shift;
    1 while s/((?:\A|[^.0-9])[-+]?\d+)(\d{3})/$1,$2/s;
    return $_;
}

from http://search.cpan.org/src/MIYAGAWA/Template-Plugin-Comma-0.04/lib/Template/Plugin/Comma.pm
行家一出手,就知有没有。
root@solaris01 # ./test.pl
$memory is 9999999
$memory_format is 9,999,999

#!/bin/perl -w
use strict;
my $memory = 9999999;
my $memory_format = $memory;
#$memory_format =~ s/((?:\A|[^.0-9])[-+]?\d+)(\d{3})/$1,$2/s
$memory_format =~ s/(\d*?)(\d{3})(\d{3})$/$1,$2,$3/;
print "\$memory is $memory \n";
print "\$memory_format is $memory_format \n";


我把上面这个子程序中的s///语句拿来改了一下,但是还不够完美。
现在能够支持从1位到9位数字的正常显示:
当$memory = 9999999的时候,程序能够正常显示为9,999,999
但是当$memory 的值有更多位数时,位数>9,它就只能显示为:999999,999,999

请各位帮忙改改这个语句:
$memory_format =~ s/(\d*?)(\d{3})(\d{3})$/$1,$2,$3/;

让它能支持更多的位数,或者说不限制位数,使用更加灵活。

改成了以下格式,支持1-16位数字:
#!/bin/perl -w
use strict;
my $memory = 9;
my $memory_format = $memory;
print "\$memory is $memory \n";
#$memory_format =~ s/((?:\A|[^.0-9])[-+]?\d+)(\d{3})/$1,$2/s
$memory_format =~ s/(\d*?)(\d{3})?(\d{3})?(\d{3})?(\d{3})?$/$1,$2,$3,$4,$5/;
print "\$memory_format is $memory_format \n";
#替换行尾的,号
$memory_format =~ s/(,+)$//;
print "\$memory_format is $memory_format \n";
#替换行首的,号
$memory_format =~ s/^,//;
print "\$memory_format is $memory_format \n";

========
root@solaris01 # ./test.pl
$memory is 9
Use of uninitialized value in concatenation (.) or string at ./test.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./test.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./test.pl line 7.
Use of uninitialized value in concatenation (.) or string at ./test.pl line 7.
$memory_format is 9,,,,
$memory_format is 9
$memory_format is 9

是否能修改成能够支持任意位数?


QUOTE:
原帖由 jjqing 于 2008-10-19 00:08 发表
是否能修改成能够支持任意位数?

搞不懂,写好的函数你不用,一定要自己重新造轮子?

[Copy to clipboard] [ - ]
CODE:
#! /usr/bin/perl

use warnings;
use strict;

sub commify {
    local $_  = shift;
    1 while s/((?:\A|[^.0-9])[-+]?\d+)(\d{3})/$1,$2/s;
    return $_;
}

my $memory_format = "9999999999999999999999999999999999999";
$memory_format = commify($memory_format);

print "$memory_format\n";



QUOTE:
原帖由 ly5066113 于 2008-10-19 10:34 发表


搞不懂,写好的函数你不用,一定要自己重新造轮子?
my $memory_format = "9999999999999999999999999999999999999";
$memory_format = commify($memory_format);
...

谢谢谢谢!
因为我不会这种调用格式,不过看了你的例子之后,明白了。

这样确实好用,不过也有个不好的地方,那就是它改变了原来的变量值了,我还要留着这个值做判断呢,所以我采用以下的格式:
                        #对数字进行格式化
                        $total_space_mb_format = $total_space_mb;
                        $total_space_mb_format =~ s/(\d*?)(\d{3})?(\d{3})?(\d{3})?(\d{3})?$/$1,$2,$3,$4,$5/;
                        $total_space_mb_format =~ s/(,+)$//;
                        $total_space_mb_format =~ s/^(,+)//;
------------------------
时光流逝,10分钟后
------------------------
改成了以下格式:
                        #对数字进行格式化
                        $total_space_mb_format = $total_space_mb;
                        $total_space_mb_format = format_number ($total_space_mb_format);



QUOTE:
原帖由 jjqing 于 2008-10-19 11:18 发表


谢谢谢谢!
因为我不会这种调用格式,不过看了你的例子之后,明白了。

这样确实好用,不过也有个不好的地方,那就是它改变了原来的变量值了,我还要留着这个值做判断呢,所以我采用以下的格式:
    ...

灵活一点嘛。
$total_space_mb_format = commify ($total_space_mb);


QUOTE:
原帖由 ly5066113 于 2008-10-19 11:29 发表


灵活一点嘛。
$total_space_mb_format = commify ($total_space_mb);

唉,好用好用。

再次修改程序。
perlfaq里面的答案:

可以用 Number::Format 模块来实现

也可以用下面的子程序:

[Copy to clipboard] [ - ]
CODE:
        sub commify {
                local $_  = shift;
                1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
                return $_;
                }

或者是下面的正则表达式:

[Copy to clipboard] [ - ]
CODE:
s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g;

落叶季节,思念季节