菜卷鱼 发表于 2024-6-25 10:15:07

数字转汉字



假如以字符串形式输入,愿意动手的,可以在现在的基础上无限扩展,最好是过亿之后,我建议把字符串拆分成2段,千万亿与千万,除了最终单位亿,其余表达是一样,因为暂时想不到哪里需要用那么大的大写数字,就不写了
(defun _Cii2BIG(num)
      (cdr (assoc num '((48 . "零")(49 . "一")(50 . "二")(51 . "三")(52 . "四")(53 . "五")(54 . "六")(55 . "七")(56 . "八")(57 . "九"))))
)
(defun num2big (num / *error* str lst _biglst _bigunit zuhe chuli1 chuli2)
(defun *error* (s)
(vl-bt)
)
(if (numberp num)
   (setq str (itoa (fix num)))
   (setq str num)
)
(setq lst (vl-string->list str))
(setq _biglst (mapcar '_Cii2BIG lst))
(setq _bigunit '("" "十" "百" "千" "万" "十" "百" "千" "亿" "十" "百" "千" "万"))
;;;;数字与单位组合
(setq zuhe (mapcar '(lambda(x y ) (strcat x y)) ( reverse _biglst) _bigunit))
;;;;处理与零组合的情况
(setq chuli1 (mapcar '(lambda(x) (if (wcmatch x "零千,零百,零十") "零"
         (if (wcmatch x "零万,零亿") (vl-string-trim "零" x) x )) ) zuhe))
;;;;处理从个位开始是0的
(while (and (> (length chuli1) 1)(wcmatch (car chuli1) "零*"))
    (setq chuli1(cdr chuli1))
)
;;;;连接处理过后的组合
(setq chuli2 (apply 'strcat (reverse chuli1)))
(cond
    ((wcmatch chuli2 "*零零零零亿*")(setq chuli2(vl-string-subst "" "零零零零亿" chuli2)))
    ((wcmatch chuli2 "*零零零亿*")(setq chuli2(vl-string-subst "亿" "零零零亿" chuli2)))
    ((wcmatch chuli2 "*零零亿*")(setq chuli2(vl-string-subst "亿" "零零亿" chuli2)))
    ((wcmatch chuli2 "*零亿*")(setq chuli2(vl-string-subst "亿" "零亿" chuli2)))
)
(cond
    ((wcmatch chuli2 "*零零零万*")(setq chuli2(vl-string-subst "" "零零零万" chuli2)))
    ((wcmatch chuli2 "*零零万*")(setq chuli2(vl-string-subst "万" "零零万" chuli2)))
    ((wcmatch chuli2 "*零万*")(setq chuli2(vl-string-subst "万" "零万" chuli2)))
)
(while (wcmatch chuli2 "*零零*")
   (setq chuli2 (vl-string-subst "零" "零零" chuli2))
)
(if (wcmatch chuli2 "一十*")
   (setq chuli2 (vl-string-subst "十" "一十" chuli2))
)
chuli2
)


newmooooon 发表于 2024-6-25 11:29:38

感谢分享!

黄翔 发表于 2024-6-25 17:01:18

本帖最后由 黄翔 于 2024-6-25 17:14 编辑

无聊.按照楼主的也写了一个
;因为(vl-string-trim"零" "六")有bug.不使用vl-string-trim函数..
(defun toChineseNum(str / nnumChineseLst result s0 s1 strLst x y)   
   (setq s0 '( "零""一""二""三""四""五""六""七""八""九" ))
   (setq strLst(mapcar '(lambda(x)(nth(- x 48)s0))(vl-string->list str)))         
   (setq s1 '("""十""百""千""万""十""百""千""亿""十""百""千""万""十""百""千""万万""十""百""千""万""十""百""千""万万"))         
   (setq result (apply 'strcat(mapcar '(lambda(x y)
       (cond((and (= x "零")(member y '("十""百""千")))"零")((and (= x "零")(member y '("万""亿" ))) y)(t (strcat x y)))
   ) strLst (reverse(mapcar '(lambda(x y) y)strLsts1)))))
    (while(vl-string-search "零零" result)(setq result (vl-string-subst "零" "零零" result)))
    (if (wcmatch result "*?零") (setq result (substr result 1 (- (strlen result)2))))
    result
)
(mapcar 'toChineseNum '("2055014010" "20001" "20010" ))
   ==>("二十亿五千五百零一万四千零一十" "二万零一" "二万零一十")

lxl217114 发表于 2024-6-26 10:19:51

大佬活跃起来了,点赞

tryhi 发表于 2024-6-26 10:32:48

本帖最后由 tryhi 于 2024-6-26 10:41 编辑

咱也来一个吧
;;将数字转换为汉字,仅支持到万亿,只支持整数
(defun num2str(num / charofcash i n tempa tempstr)
      (setq s0 '( "零""一""二""三""四""五""六""七""八""九" ))
      (setq s1 '("""十""百""千""万""十""百""千""亿""十""百""千""万"))
      (setq num (rtos num 2 0));转字符串
      (setq i -1 CharOfCash "")
      (setq n(strlen num))
      (repeat n
                (setq i(1+ i))
                (setq TempStr(substr num (- n i)1))
                (setq TempStr (nth (atoi TempStr) s0))
                (if (/= "零" TempStr)
                        (setq TempStr (strcat TempStr (nth i s1)))
                )
                (setq tempa(substr CharOfCash1 2))
                (if (or (/= TempStr "零")(not(or (wcmatch tempa "零,万,亿")(= tempa ""))))
                        (setq CharOfCash(strcat TempStr CharOfCash))
                )
      )
      (setq temp(substr CharOfCash 1 4))
      (if (= "一十"temp)(substr CharOfCash 3)CharOfCash);去掉一十
)

(num2str 5012500030101)
;===>"五万零一百二十五亿零三万零一百零一"
(num2str 5012500030101)
;===>"五万零一百二十五亿零三万零一百零一"


另外还有一个汉字转数字的函数 [源码]数字转为汉字函数、汉字数字互转
(str2num "一千零八十万八千七百六十七")
;==> 10808767

MZ_li 发表于 2024-6-30 20:18:41

大神是真的多

阿猪蛋 发表于 2024-7-1 09:54:53

大佬活跃起来了,点赞
页: [1]
查看完整版本: 数字转汉字