免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: q1208c
打印 上一主题 下一主题

如何正确添加 千位分隔符? [复制链接]

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
11 [报告]
发表于 2014-09-01 11:33 |只看该作者
回复 10# iamlimeng

我没看过 小骆驼.  

精通正则 上的例子, 是一个整数. 没有小数. 所以, 我才拿出来问了一下. 因为按照约定, 小数部分, 是不能添加分隔的. 只有整数部分才需要.
   

论坛徽章:
0
12 [报告]
发表于 2014-09-02 21:31 |只看该作者
本帖最后由 yeahnoob 于 2014-09-02 23:01 编辑

实际应用环境中,可能是直接用cpan现成的模块,比如
  1. use CLDR::Number::Format::Decimal;
复制代码
,生产效率会比自己动手高很多。
比如下面这样子:

  1. Perl> use Number::Format;

  2. Perl> my $a= new Number::Format;
  3. Number::Format=HASH(0xe1c558)

  4. Perl> my $b=$a->format_number("-99123123123.4564560",2);
  5. -99,123,123,123.46
复制代码
但是如果想作为单独的一个例子——比较费神——使劲Google了一会儿,结果如下:
perldoc perllocale里的一个例子
  1. use POSIX qw(locale_h);

  2.            # Get some of locale's numeric formatting parameters
  3.            my ($thousands_sep, $grouping) =
  4.                    @{localeconv()}{'thousands_sep', 'grouping'};

  5.            # Apply defaults if values are missing
  6.            $thousands_sep = ',' unless $thousands_sep;

  7.            # grouping and mon_grouping are packed lists
  8.            # of small integers (characters) telling the
  9.            # grouping (thousand_seps and mon_thousand_seps
  10.            # being the group dividers) of numbers and
  11.            # monetary quantities.  The integers' meanings:
  12.            # 255 means no more grouping, 0 means repeat
  13.            # the previous grouping, 1-254 means use that
  14.            # as the current grouping.  Grouping goes from
  15.            # right to left (low to high digits).  In the
  16.            # below we cheat slightly by never using anything
  17.            # else than the first grouping (whatever that is).
  18.            if ($grouping) {
  19.                @grouping = unpack("C*", $grouping);
  20.            } else {
  21.                @grouping = (3);
  22.            }

  23.            # Format command line params for current locale
  24.            for (@ARGV) {
  25.                $_ = int;    # Chop non-integer part
  26.                1 while
  27.                s/(\d)(\d{$grouping[0]}($|$thousands_sep))/$1$thousands_sep$2/;
  28.                print "$_";
  29.            }
  30.            print "\n";
复制代码
有人写的另外一个例子,这个例子的匹配表达也很容易被读懂。
  1. # from Andrew Johnson <[email]ajohnson@gpu.srv.ualberta.ca[/email]>
  2.     sub commify {
  3.        my $input = shift;
  4.         $input = reverse $input;
  5.         $input =~ s<(\d\d\d)(?=\d)(?!\d*\.)><$1,>g;
  6.         return reverse $input;
  7.     }
复制代码
上面这个sub 可以解决带小数点的数字添加千位分隔符问题
——例如对于具体的数字$a=123123123.456456,按如下步骤转换:

  1. yeahnoob@yeahnoob-desktop:~$ perlconsole
  2. Perl Console 0.4
  3. Perl> my $a=123123123.456456;
  4. 123123123.456456

  5. Perl> $a=reverse $a;
  6. 654654.321321321

  7. Perl> $a =~ s<(\d\d\d)(?=\d)(?!\d*\.)><$1,>g;
  8. 2

  9. Perl> $a=reverse $a;
  10. 123,123,123.456456

  11. Perl> $a
  12. 123,123,123.456456

  13. Perl>
复制代码

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
13 [报告]
发表于 2014-09-03 08:28 |只看该作者
回复 12# yeahnoob

感谢兄弟的回复.

其实我平时用到这种给数字加 千位分隔的情况并不多. 这次问这个, 只是因为前面帮一个兄弟看问题的时候, 忽然发现了新问题.

论坛徽章:
3
2015亚冠之阿尔希拉尔
日期:2015-08-15 16:33:2215-16赛季CBA联赛之四川
日期:2016-01-03 13:37:0515-16赛季CBA联赛之四川
日期:2016-06-13 15:53:36
14 [报告]
发表于 2014-09-12 21:32 |只看该作者
sub COMMA
{

local $_  = shift;
  
  1 while   s/^([-+]?\d+)(\d{3})/$1,$2/g;         #before point split with ',' every 3 digit
  
  1 while s/(.?)(\d{3})(\d+)/$1$2,$3/;              #after point split with ',' every 3 digit
  
   

return $_;

}



q1208c 发表于 2014-08-26 17:11
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4151864

刚才看到这个贴子, 目测了一下, 也顺便 ...

论坛徽章:
0
15 [报告]
发表于 2014-09-14 17:15 |只看该作者
perl -le  '$a=123445454;$a =~ s/(?<=\d)(?=(\d{3})+$)/,/g;print $a'

论坛徽章:
0
16 [报告]
发表于 2014-09-14 17:56 |只看该作者
felix0608 发表于 2014-09-14 17:15
perl -le  '$a=123445454;$a =~ s/(?


这段code,遇上输入有小数点,就不能正常工作,LZ也有提到。

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
17 [报告]
发表于 2014-09-15 06:55 |只看该作者
回复 15# felix0608

这个结果应该是有点小问题的.
  1. perl -le  '$a=123445454.234123412341;$a =~ s/(?<=\d)(?=(\d{3})+$)/,/g;print $a'
复制代码

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
18 [报告]
发表于 2014-09-15 06:58 |只看该作者
回复 14# minirain

小数部分, 应该是没有千位符的吧?
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP