出题:如何优雅转换大写数字? 19 转成 十九 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
jin5354
V2EX    程序员

出题:如何优雅转换大写数字? 19 转成 十九

  •  
  •   jin5354
    jin5354 2017 年 9 月 6 日 6321 次点击
    这是一个创建于 3104 天前的主题,其中的信息可能已经有所发展或是发生改变。
    天杀的需求竟然要展示大写数字,我要和产品搏命

    0 -> 零
    5 -> 五
    19 -> 十九
    20 -> 二十
    21 -> 二十一
    100 -> 一百
    第 1 条附言    2017 年 9 月 6 日
    我知道有轮子。
    本来是想看看这种繁琐的小需求,有没人有搞出优雅姿势让我学习学习(比如 codewar 上的炫酷单行题解),所以说是出题。
    46 条回复    2017-09-07 11:25:19 +08:00
    Light3
        1
    Light3  
       2017 年 9 月 6 日   3
    https://github.com/wilon/php-number2chinese

    一会给下我帮你搜的电费
    xfspace
        2
    xfspace  
       2017 年 9 月 6 日 via Android
    数字前加个“大写”

    大写 0
    大写 1

    没毛病
    Famio
        3
    Famio  
       2017 年 9 月 6 日
    上古:<big>1234567890</big>
    Sanko
        4
    Sanko  
       2017 年 9 月 6 日 via Android
    记得给二楼转一下电费
    顺带给我发一下流量费
    zonyitoo
        5
    zonyitoo  
       2017 年 9 月 6 日
    自己写一个到底有多难?
    misaka19000
        6
    misaka19000  
       2017 年 9 月 6 日 via Android
    赔我点进来的流量费
    asj
        7
    asj  
       2017 年 9 月 6 日
    这个自己写写也就一两个小时吧
    maplerecall
        8
    maplerecall  
       2017 年 9 月 6 日 via Android
    @asj 这个很简单吧,十分钟就够了…
    yuanfnadi
        9
    yuanfnadi  
       2017 年 9 月 6 日
    这种普遍的需求,git 上任何语言肯定有轮子。
    debuggerx
        10
    debuggerx  
       2017 年 9 月 6 日   1

    当年自学 java 的笔记……
    虽然早就不写 java 了,这个小本子却总是习惯性地装在包里。。。
    0ZXYDDu796nVCFxq
        11
    0ZXYDDu796nVCFxq  
       2017 年 9 月 6 日 via iPhone
    提这需求不是很正常吗?
    再说调个轮子也就两行代码
    jianleer
        12
    jianleer  
       2017 年 9 月 6 日
    jianleer
        13
    jianleer  
       2017 年 9 月 6 日
    看错了,以为是日常使用,请忽略楼上截图
    ipconfiger
        14
    ipconfiger  
       2017 年 9 月 6 日
    大写应该是 拾玖 才对吧
    kslr
        15
    kslr  
       2017 年 9 月 6 日
    arr [
    0 = 零
    1 = 壹
    2 = 贰
    3 = 叁
    ]

    第 1 天
    第 arr[1]天
    aksoft
        16
    aksoft  
       2017 年 9 月 6 日
    @debuggerx 你这个本子 我喜欢
    8Cangtou
        17
    8Cangtou  
       2017 年 9 月 6 日
    reduce~~~~map~~~~
    silymore
        18
    silymore  
       2017 年 9 月 6 日 via iPhone
    可以来个 web api
    ipconfiger
        19
    ipconfiger  
       2017 年 9 月 6 日
    这个单行搞不出来, 就算你憋着搞出来了, 一是无法容错, 二是无法调试, 三是没有可读性 所以一点实用价值也没有
    AlisterTT
        20
    AlisterTT  
       2017 年 9 月 6 日
    alfred 有个 workflow 有这功能的,你可以参考一下 https://github.com/yourtion/Alfred_NumToCny
    ShiHou
        21
    ShiHou  
       2017 年 9 月 6 日
    debuggerx
        22
    debuggerx  
       2017 年 9 月 6 日
    @debuggerx 只记了记不住的正则替换部分,完整方法和测试如下:

    public class Int2Big {
    static String int2big(int src) {
    final String num[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    final String unit[] = {"圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};
    String dst = "";
    int count = 0;
    while (src > 0) {
    dst = (num[src % 10] + unit[count]) + dst;
    src = src / 10;
    count++;
    }
    return dst.replaceAll("零[仟佰拾]", "零").replaceAll("零+万", "万")
    .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
    .replaceAll("零+", "零").replaceAll("零圆", "圆");
    }

    public static void main(String[] args) {
    System.out.println(int2big(123004506)); //-->壹亿贰仟叁佰万肆仟伍佰零陆圆
    System.out.println(int2big(6523464)); //-->陆佰伍拾贰万叁仟肆佰陆拾肆圆
    System.out.println(int2big(1001000100));//-->壹拾亿零壹佰万零壹佰圆
    System.out.println(int2big(808)); //-->捌佰零捌圆
    }
    }
    haohaozaici
        23
    haohaozaici  
       2017 年 9 月 6 日
    https://gist.github.com/binjoo

    记得给电费。。。
    haohaozaici
        24
    haohaozaici  
       2017 年 9 月 6 日
    https://gist.github.com/binjoo/6028263

    记得给电费。。。 这个。。。
    BlackBerry
        25
    BlackBerry  
       2017 年 9 月 6 日
    0 零
    ipconfiger
        26
    ipconfiger  
       2017 年 9 月 6 日
    Python 一行的实现方式 之一:
    "".join(list(reversed(["%s%s" % (["", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(list(reversed(seq))[idx])], unit) for idx, unit in enumerate(reversed(reduce(list.__add__, [ ["仟", "佰", "拾", big_unit] for big_unit in ["兆", "亿", "万", ""]]))) if idx<len(seq)])))

    能实现千兆以下数字的大写转换

    But 并没有什么卵用, 为了实现一行写下, 牺牲了效率, 这是其一, 可读性差, 这是其二, 且, 对于 19 => 拾玖 这种省略转换, 并不支持, 会转换成 壹拾玖 所以, 不要这么干
    mengyaoss77
        27
    mengyaoss77  
       2017 年 9 月 6 日
    @ipconfiger #26 对于发票上面写大写的话 好像 19 就需要写成 一十九吧
    wenzhoou
        28
    wenzhoou  
       2017 年 9 月 6 日 via Android
    19 转成 十九 优雅还是 一十九 优雅。119 呢?
    ipconfiger
        29
    ipconfiger  
       2017 年 9 月 6 日
    @mengyaoss77 还有别的问题, 比如中间全是 0 的时候省略的问题
    ipconfiger
        30
    ipconfiger  
       2017 年 9 月 6 日
    再改一版:
    lambda seq:"".join(list(reversed([("%s%s" % (["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(list(reversed(seq))[idx])], unit)) if idx>0 or int(list(reversed(seq))[1]) else ("零%s" % ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(list(reversed(seq))[idx])]) for idx, unit in enumerate(reversed(reduce(list.__add__, [ ["仟", "佰", "拾", big_unit] for big_unit in ["兆", "亿", "万", ""]]))) if idx<len(seq) and int(list(reversed(seq))[idx])>0])))

    支持了中间一堆 0 的情况, but, 代码完全没有可读性了, Orz
    a87150
        31
    a87150  
       2017 年 9 月 6 日
    @ipconfiger from functools import reduce 我信了你的邪
    Kisesy
        32
    Kisesy  
       2017 年 9 月 6 日
    @ShiHou 你这个有点像 youtube 上关注数的显示方式,太机械
    比如 2000105 会翻成 二百万一百五,掉了中间的零还行,后面的也掉了,读出来成了 2000150
    应该是 二百万零一百零五
    ipconfiger
        33
    ipconfiger  
       2017 年 9 月 6 日
    @a87150 并没有啊, 不信你试试, 2.7 哈
    ShiHou
        34
    ShiHou  
       2017 年 9 月 6 日
    @Kisesy 更新了下。
    KaKaGoSki
        35
    KaKaGoSki  
       2017 年 9 月 6 日
    百度不会吗
    sirm2z
        36
    sirm2z  
       2017 年 9 月 6 日
    js 自带:

    ```
    var number = 1000
    number.toLocaleString('zh-Hans-CN-u-nu-hanidec')
    ```
    Kisesy
        38
    Kisesy  
       2017 年 9 月 6 日
    @ShiHou 好多了,虽然还有不少数掉零,读起来不顺,不过念出来不至于错了,不错
    Kisesy
        39
    Kisesy  
       2017 年 9 月 6 日
    @ShiHou 还有一个.. 20001 翻成了 二万一
    ipconfiger
        40
    ipconfiger  
       2017 年 9 月 6 日
    第二种方法:

    lambda seq: "".join(reversed(["".join([prefix, ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(num)], unit]) for prefix, num, unit in [["零", tp[0], tp[1]] if idx<(len(seq)-1) and int(seq[len(seq)-idx-2])<1 else ["", tp[0], tp[1]] for idx, tp in enumerate(zip(list(reversed(seq)) , list(reversed(reduce(list.__add__, [ ["仟", "佰", "拾", big_unit] for big_unit in ["兆", "亿", "万", ""]]))))) if int(tp[0])]]))
    ipconfiger
        42
    ipconfiger  
       2017 年 9 月 6 日   1
    终极一行写法, 解决了大部分已知问题, 并且支持输入数字

    lambda number_string: (lambda seq: "".join(reversed(["".join(["".join([p, ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(n)], u]) for p, n, u in reversed(s[0])]) + s[1] for s in [(lambda sub_seq: [[["零", tp[0], tp[1]] if i<(len(sub_seq)-1) and int(sub_seq[i+1])< 1 else ["", tp[0], tp[1]] for i, tp in enumerate(zip(sub_seq, ["", "拾", "佰", "仟"])) if int(tp[0])], unit])(seq[idx*4:(idx+1)*4] or []) for idx, unit in enumerate(["", "万", "亿", "兆", "京"])] if s[0]])))("".join(reversed(str(number_string))))
    natforum
        43
    natforum  
       2017 年 9 月 6 日
    @debuggerx 大佬,收徒吗
    zhx1991
        44
    zhx1991  
       2017 年 9 月 6 日
    一百二 120
    两百零二 202
    两百二 220
    asj
        45
    asj  
       2017 年 9 月 7 日
    @maplerecall
    我没做过,不过练习过几次数字转成英文的。反正我自己的水平是需要 1,2 个小时的。
    转汉字可能细节上有不同,我应该还是达不到十分钟完全解决的。
    calebx
        46
    calebx  
       2017 年 9 月 7 日
    https://github.com/calebx/number_to_cn
    这是我多年前搞的。

    可以看看,其实挺复杂的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2466 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 01:45 PVG 09:45 LAX 17:45 JFK 20:45
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86