标题: [原创代码] [造轮子]Perl脚本金额数字转中文大写 [打印本页]
作者: 523066680 时间: 2014-9-12 20:41 标题: [造轮子]Perl脚本金额数字转中文大写
保存为utf-8文本格式。
没有做太多测试,欢迎测试BUG,欢迎各位分享更简单的代码。- use utf8;
- use Encode;
- binmode(STDOUT, ":encoding(gbk)");
-
- our @unit_f = ("", "角"); #分省略,最后补上
- our @part = ("", "萬", "亿"); #元省略,最后补上
- our @unit = ("", "拾", "佰", "仟"); #同上
- our @cnum = qw/零 壹 贰 叁 肆 伍 陆 柒 捌 玖 拾/;
-
- my ($inp, $str, $sect) = (undef, "", "");
- my ($ni, $nf, $i);
- my ($fa, $fb);
- $inp=50050001.51;
- ($ni, $nf) = split(/\./, sprintf("%.2f", $inp));
-
- $i = 0;
- #处理整数部分
- while ($ni ne "") {
- $ni=~s/(\d{0,4})$//; #每四位数为一段进行截取
- $sect = &func($1);
- # 如果某段大写返回为空(全0的情况),则缩略
- # 例如壹亿,而不是壹亿萬
- if ($sect ne "") {
- $str = $sect . $part[$i] . $str;
- }
- $i++;
- }
- $str = $str."元";
-
- #处理角和分
- @unit = (@unit_f);
- $sect = &func($nf);
- if ($sect ne "") {
- $str = $str . $sect;
- $str = $str ."分" unless ($sect=~/角$/);
- }
- print $str;
-
- sub func {
- our @unit;
- our @cnum;
- my @ints = reverse( split("", $_[0]) ); #反转成 (个,十,佰,仟)
- my $prev = 1;
- my $begin = 0;
- my $i;
- my $str = "";
-
- #如果低位连续出现零,略过。
- #例如,一百零拾零元简写为:一百元
- while (
- defined $ints[$begin]
- and
- $ints[$begin] == 0
- ) {
- $begin++;
- }
-
- foreach $i ($begin .. $#ints) {
- if (
- $ints[$i] == 0
- ) {
- if ($prev != 0) {
- $str = $cnum[$ints[$i]] . $str; #零
- $prev = 0;
- }
- next;
- }
- $prev = $ints[$i];
- $str = $cnum[$ints[$i]] . $unit[$i] . $str;
- }
- return $str;
- }
复制代码
作者: CrLf 时间: 2014-9-12 23:07
马克
作者: neorobin 时间: 2014-9-15 13:03
本帖最后由 neorobin 于 2014-9-15 13:39 编辑
没学 PERL, CMD 弄了个
零零, 你去哪了, 我好想你, 我有好多好多 money 哦, 你快回来.....- @echo off & title RMB & chcp 936 & setlocal enabledelayedexpansion
- set "unit=仟佰拾个" & set "unit1=角分" & set "num=零壹贰叁肆伍陆柒捌玖"
-
- for %%x in (
- 0
- 0.00
- 8
- 0.2
- 0.0
- 987654321.12
- 0.09
- 3.02
- 7.60
- 50.00
- 987654321
- 987654320
- 987654300
- 987654000
- 987650000
- 987650321
- 987654021
- 987654301
- 987650021
- 987654001
- 987650301
- 987650001
- 900000321
- 900000000
- 900000021
- 900000001
- 900000000.03
- 900000000.00
- 900000000.10
- ) do for /f "tokens=1-2 delims=." %%a in (
- "%%x"
- ) do (
- echo %%x
- set "dgt=%%a" & set "I="
- for /l %%i in (-16 1 -1) do (
- set /a "j=%%i+1, s=j>>31, j=s&j|~s&1, k=(%%i+1) %% 4 - 1"
- for /f "tokens=1-2" %%j in ("!j! !k!") do (
- if "!dgt:~%%i,%%j!" neq "" (
- for %%n in (!dgt:~%%i^,%%j!) do set "I=!I!!num:~%%n,1!!unit:~%%k,1!"
- )
- )
- )
-
- set "I=A!I:~-24,-16!亿!I:~-16,-8!万!I:~-8!元"
- set "I=!I:A亿=A!"
- set "I=!I:A万=A!"
-
- set "I=!I:零个=个!"
- set "I=!I:零拾个=个!"
- set "I=!I:零佰个=个!"
- set "I=!I:零仟个=个!"
- set "I=!I:个=!"
-
- set "I=!I:亿万元=亿元!"
- set "I=!I:亿万=亿零!"
- set "I=!I:零仟=零!"
- set "I=!I:零佰=零!"
- set "I=!I:零拾=零!"
- set "I=!I:零零=零!"
- set "I=!I:零零=零!"
-
- set "T=%%b00" & set "F="
- for %%i in (0 1) do for %%n in (!T:~%%i^,1!) do set "F=!F!!num:~%%n,1!!unit1:~%%i,1!"
-
- set "F=!F:零分=D!"
- set "F=!F:零角D=整!"
- set "F=!F:零角=零!"
- set "F=!F:D="!
-
- set "R=!I!!F!"
- set "R=!R:A元整=零元整!"
- set "R=!R:A元零=!"
- set "R=!R:A元=!"
- set "R=!R:A=!"
-
- echo !R! & echo.
- )
-
- pause
复制代码
作者: 523066680 时间: 2014-9-15 14:51
本帖最后由 523066680 于 2014-9-15 15:17 编辑
回复 3# neorobin
对比之下发现我那个漏了零元整以及零点几的情况。
另:
nerobin有没有学C/C++,看之前的分析代码应该是会C的
作者: neorobin 时间: 2014-9-15 15:28
回复 4# 523066680
这个东东要精确而完整的的把逻辑 表达出来, 还真有点耗脑筋, 与其说代码的技术问题, 不如说是逻辑的表述, 整理. 我的代码, 我也没法证明是对的. 不管了.
会一点 C
作者: 523066680 时间: 2014-9-15 15:44
回复 5# neorobin
早一点撸C/C++,我觉得现阶段的nerobin需要更强大的语言去实现那些想法。
关键是有些轮子造出来后,后期维护起来方便很多。批处理写复杂了,时间久了就算有BUG也不想改了。
我觉得。
作者: neorobin 时间: 2014-9-15 15:50
回复 6# 523066680
最早时用 QB 弄过立方体旋转, 可没有要用 C/C++ 开发 3D 引擎类的大志, BAT 不用编译, 随手就撸, 纯属自娱
作者: neorobin 时间: 2014-9-15 15:59
回复 6# 523066680
想起了经典歌词啊: I CAN SING MY ABC
作者: 523066680 时间: 2014-9-15 16:10
回复 7# neorobin
好吧。
作者: CrLf 时间: 2014-9-15 18:57
打一架!打一架!
前排兜售花生瓜子小板凳
作者: 523066680 时间: 2014-9-15 20:26
回复 10# CrLf
因为PHP是世界上最好的语言?!
作者: CrLf 时间: 2014-9-15 20:34
888套餐=铂金折叠小板凳+青岛7°啤酒12听+百联瓜子(大)一包+爽口梅一包+香辣青豆一包+香酥薯片一包+炭烧手撕鱿鱼丝一包+大爆米花一份+豪华果盘一盘+卤味一份+冰水煮花生一份+钻石会员卡一张
作者: 523066680 时间: 2014-9-15 21:19
回复 12# CrLf
肚腩照明月?
作者: CrLf 时间: 2014-9-15 21:52
回复 13# 523066680
没看懂,百度了一下貌似是个ID,那么你认错了...
作者: 523066680 时间: 2014-9-15 22:04
本帖最后由 523066680 于 2014-9-15 22:09 编辑
回复 14# CrLf
我是说你晚上吃这么多是要撑破肚皮晒月亮么? CU那个肚腩照明月Perl好像很老练啊。
走,我们去文字消遣区。
作者: 523066680 时间: 2014-9-16 08:58
本帖最后由 523066680 于 2014-9-16 08:59 编辑
稍微做了改进- use IO::Handle;
- use utf8;
- use Encode;
- STDOUT->autoflush(1);
- STDERR->autoflush(1);
- binmode(STDOUT, ":encoding(gbk)");
-
- our @unit_f = ("", "角"); #分省略,最后补上
- our @part = ("", "萬", "亿"); #元省略,最后补上
- our @unit = ("", "拾", "佰", "仟"); #同上
- our @cnum = qw/零 壹 贰 叁 肆 伍 陆 柒 捌 玖 拾/;
-
- foreach (
- 1.01,
- 900000000,
- 0.0,
- 7.2,
- 12300100.12,
- 101010101
- ) {
- printf &main($_) . "\n";
- }
- <STDIN>;
-
- sub main {
- my $inp = shift;
- my ($str, $sect) = ("", "");
- my ($ni, $nf, $i) = ("", "", undef);
-
- return "零元" if ($inp == 0);
-
- #整数部分和小数部分
- ($ni, $nf) = split(/\./, sprintf("%.2f", $inp));
-
- #处理整数部分
- $i = 0;
- while ($ni ne "") {
- $ni=~s/(\d{0,4})$//; #每四位数为一段进行截取
- $sect = &func($1, \@unit);
- # 如果某段大写返回为空(0000),则缩略
- # 例如壹亿,而不是壹亿萬
- if ($sect ne "") {
- $str = $sect . $part[$i] . $str;
- }
- $i++;
- }
- $str .="元" if ($str ne "");
-
- #处理角和分
- $sect = &func($nf, \@unit_f);
- if ($sect ne "") {
- $str = $str . $sect;
- $str = $str ."分" unless ($sect=~/角$/);
- }
-
- return $str;
- }
-
- sub func {
- our @cnum;
- my ($num, $unit) = (shift, shift);
- my @ints = reverse( split("", $num) ); #反转成 (个,十,佰,仟)
- my $prev = 1;
- my $begin = 0;
- my $i;
- my $str = "";
-
- #略过低位连续出现的零
- #例如,一百零拾零元简写为:一百元
- while (
- defined $ints[$begin]
- and
- $ints[$begin] == 0
- ) {
- $begin++;
- }
-
- foreach $i ($begin .. $#ints) {
- if (
- $ints[$i] == 0
- ) {
- if ($prev != 0) {
- $str = $cnum[$ints[$i]] . $str; #零
- $prev = 0;
- }
- next;
- }
- $prev = $ints[$i];
- $str = $cnum[$ints[$i]] . $unit->[$i] . $str;
- }
- return $str;
- }
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |