标题: [文本处理] 批处理把中文数字转阿拉伯数字(0~2147483647) [打印本页]
作者: aloha20200628 时间: 2022-8-9 19:47 标题: 批处理把中文数字转阿拉伯数字(0~2147483647)
本帖最后由 aloha20200628 于 2024-3-27 11:08 编辑
第一段是测试代码
第二个封装函数/子过程,是母函数 - 分段求和函数
第三个是封装函数/子过程,是子函数 - 最小段位转换函数- @echo off &setlocal enabledelayedexpansion
- :[Loop] // 测试代码》中文数字转为阿拉伯数字(0-2147483647)
- set "cn="
- set/p cn="输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:"
- if not defined cn endlocal&exit/b
- (call :ChangeCnToAn !cn! an)
- echo,n=!an!
- goto [Loop]
-
- :: 分段求和函数》最大输出范围={ 0~2147483647 }
- :ChangeCnToAn // %1=中文数字符串(实值) %2=返回值变量名
- if "%~1"=="零" (set "%~2=0")&exit/b
- set "#cn#=%~1" &set "Yn=100000000"
- if "!#cn#:~-1!"=="亿" (
- (call :ChangeCnToAn9999 !#cn#:~,-1! #n)
- (set/a "%~2=!#n!*!Yn!")&exit/b
- )
- set "#cn#=!#cn#:*亿=!" &set "#cn=!#cn#:零=!"
- if "!#cn:万=!" neq "!#cn!" (for /f "tokens=1-2 delims=万" %%a in ("!#cn!") do (
- (call :ChangeCnToAn9999 %%a nL)
- set/a "#n=!nL!*10000"
- if "%%b" neq "" (
- (call :ChangeCnToAn9999 %%b nR)
- set/a "#n+=!nR!"
- )
- )) else (call :ChangeCnToAn9999 !#cn! #n)
- if "!#cn#!" neq "%~1" for /f "tokens=1-2 delims=亿" %%a in ("%~1") do (
- (call :ChangeCnToAn9999 %%a nY)
- (set/a "#n+=!nY!*!Yn!")
- )
- set "%~2=!#n!" &exit/b
-
- :: 最小段位转换函数》输出范围={ 0~9999 }
- :ChangeCnToAn9999 // %1=中文数字符串(实值) %2=返回值变量名
- if "%~1"=="零" set "%~2=0"&exit/b
- set "cn#=%~1"&set "cn#=!cn#:零=!"&set "uList=十,百,千"
- set/a "n#=0,一=1,二=2,三=3,四=4,五=5,六=6,七=7,八=8,九=9,十=10,百=100,千=1000"
- for /L %%k in (0, 2, 6) do if "!cn#:~%%k,1!" neq "" (
- set "n2c=!cn#:~%%k,2!" &set "nc1=!n2c:~0,1!" &set "nc2=!n2c:~1,1!"
- if "!nc2!"=="" (set/a n#+=!nc1!) else for %%c in (!nc2!) do (
- if "!uList:%%c=!" neq "!uList!" (set/a n#+=!nc1!*!nc2!) else (set/a n#+=!nc1!+!nc2!)
- )
- )
- set "%~2=!n#!" &exit/b
复制代码
作者: hfxiang 时间: 2022-8-10 08:58
测试好像不是俺想要的结果?
D:\bat_test>中文数字转阿拉伯数字.bat
输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:一万九千七
n=9007
作者: qixiaobin0715 时间: 2022-8-10 09:40
回复 2# hfxiang
你输入的不规范:一万九千七百
作者: hfxiang 时间: 2022-8-10 13:21
回复 3# qixiaobin0715
还是不行,测试如下:
输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:一万九千七百
n=9701
请展示一下你的规范输入后的测试结果,谢谢
作者: qixiaobin0715 时间: 2022-8-10 13:43
- 输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:一万九千七百
- n=19700
- 输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:一百零一
- n=101
- 输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:一亿零二十万零伍佰零一
- n=100200001
- 输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:
复制代码
作者: qixiaobin0715 时间: 2022-8-10 13:47
不知道楼主的规范写法是怎样的?最后一个未通过。
作者: hfxiang 时间: 2022-8-10 13:59
回复 5# qixiaobin0715
谢谢。从显示上看只有1个不正常。
不知为何,俺测试的好基本上都不正常。估计代码显示到网页后复制到本地时字符有出入。
作者: qixiaobin0715 时间: 2022-8-10 14:36
回复 7# hfxiang
idwma在此帖中http://bbs.bathome.net/viewthrea ... mp;page=1#pid258116的思路靠谱,分段拼接,可突破字符限制。
作者: aloha20200628 时间: 2022-8-10 15:43
中文数字的单位字符只针对》零十百千万亿,未考虑繁体字如 佰...
作者: qixiaobin0715 时间: 2022-8-10 16:15
回复 9# aloha20200628
抱歉搞错了!!!
作者: qixiaobin0715 时间: 2022-8-11 09:01
本帖最后由 qixiaobin0715 于 2022-8-11 09:15 编辑
按照idwma在其它帖子中的思路进行分段拼接,可以突破2147483647的限制,适合小于等于“九千九百九十九亿九千九百九十九万九千九百九十九”的值,再大有点复杂,未加考虑,处理一般情况就足够了:- @echo off
- setlocal enabledelayedexpansion
- set str=九千九百九十九亿九千九百九十九万九千九百九十九
- set str=!str:零=!
- set str=!str:亿=亿 !
- set str=!str:万=万 !
- set _十=10
- for %%i in (一 二 三 四 五 六 七 八 九) do (
- set /a x+=1
- set /a _%%i=!x!
- set y=1
- for %%j in (十 百 千) do (
- set /a y*=10
- set /a _%%i%%j=!x!*!y!
- )
- )
- for %%i in (!str!) do (
- set Part=%%i
- if !Part:~-1!==亿 (
- set Part1=!Part:~,-1!
- ) else if !Part:~-1!==万 (
- set Part2=!Part:~,-1!
- ) else (
- set Part3=%%i
- )
- )
- for /l %%i in (1,1,3) do (
- if defined Part%%i (
- set Part%%i=!Part%%i:千=千 !
- set Part%%i=!Part%%i:百=百 !
- set Part%%i=!Part%%i:十=十 !
- for %%j in (!Part%%i!) do set /a m%%i+=_%%j
- )
- set /a m%%i+=10000
- set m%%i=!m%%i:~1!
- )
- for /f "tokens=* delims=0" %%i in ("!m1!!m2!!m3!") do echo,%%i
- pause
复制代码
保存为ANSI编码。
代码是按照一般思路写的,考虑的还不算成熟,应当还有更简洁的方法。
作者: qixiaobin0715 时间: 2022-8-11 14:15
先以亿分为2段,再将2段以万分别分为2段,总体分为4段,最后拼接,可以扩展为16位数字。
作者: hfxiang 时间: 2024-3-27 11:42
回复 1# aloha20200628
5楼之前提出的问题还在- 输入一个中文数字【零 - 二十一亿四千七百四十八万三千六百四十七】:一亿零二十万零伍佰零一
- n=100200001
复制代码
作者: aloha20200628 时间: 2024-3-27 12:00
回复 13# hfxiang
中文数字的输入格式应为中文小写格式》亿万千百十...而佰须改为百
作者: hfxiang 时间: 2024-3-27 12:12
回复 14# aloha20200628
之前9楼的回复俺都已看到,但你认为的大写,其在现实应用中是存在的(是俺太不知足了,抱歉)。
作者: aloha20200628 时间: 2024-3-27 13:49
回复 15# hfxiang
中文数字大小写混合输入的问题,其实可用一个前置字典替换解决。此处不再复贴一楼全版代码了,有需求者可将如下代码行插入一楼代码第5行之后即可。- for %%v in ("壹=一", "贰=二", "叁=三", "肆=四", "伍=五", "陆=六", "柒=七", "捌=八", "玖=九", "拾=十", "佰=百", "仟=千") do (set "cn=!cn:%%~v!")
复制代码
作者: hfxiang 时间: 2024-3-27 18:45
回复 16# aloha20200628
把楼主的ChangeCnToAn9999子过程修改如下,经不完全测试,好像也能实现对大写的兼容:- :: 最小段位转换函数》输出范围={ 0~9999 }
- :ChangeCnToAn9999 // %1=中文数字符串(实值) %2=返回值变量名
- if "%~1"=="零" set "%~2=0"&exit/b
- set "cn#=%~1" &set "cn#=!cn#:零=!"&set "uList=十,拾,百,佰,千,仟"
- set/a "n#=0,一=1,二=2,三=3,四=4,五=5,六=6,七=7,八=8,九=9,十=10,百=100,千=1000"
- set/a "n#=0,壹=1,贰=2,叁=3,肆=4,伍=5,陆=6,柒=7,捌=8,玖=9,拾=10,佰=100,仟=1000"
- for /L %%k in (0,2,6,8,10,12) do if "!cn#:~%%k,1!" neq "" (
- set "n2c=!cn#:~%%k,2!" &set "nc1=!n2c:~0,1!" &set "nc2=!n2c:~1,1!"
- if "!nc2!"=="" (set/a n#+=!nc1!) else for %%c in (!nc2!) do (
- if "!uList:%%c=!" neq "!uList!" (set/a n#+=!nc1!*!nc2!) else (set/a n#+=!nc1!+!nc2!)
- )
- )
- set "%~2=!n#!" &exit/b
复制代码
作者: aloha20200628 时间: 2024-3-27 19:23
回复 17# hfxiang
只要能经受各种测试就好...
作者: terse 时间: 2024-3-31 19:22
本帖最后由 terse 于 2024-4-1 08:08 编辑
处理大数
头两行加上了
修正一下亿位的处理,发现bug再修正- @echo off&setlocal enabledelayedexpansion
- set/a "零=0,一=1,二=2,三=3,四=4,五=5,六=6,七=7,八=8,九=9,十=10,百=100,千=1000,万=10000,亿=100000"
- set "str=八十二亿零十"
- set "s=!str!
- if "!s:~16!" neq "" (set len=16&set "s=!s:~16!") else set len=0
- set "s=!s!fedcba9876543210"
- set /a "len+=0x!s:~16,1!,result=content=num=0"
- set "stry="
- for /l %%i in (0,1,!len!) do for /f %%j in ("!str:~%%i,1!") do (
- if !%%j! geq 10 (
- if !%%j! gtr 1000 (
- if !%%j! gtr 10000 (
- set /a stry=result+content+num,result=content=0"
- set stry=!stry!00000000
- )else set /a "content=(content+num)*%%j,result+=content,content=0"
- ) else set /a "num+=^!num,content+=num*%%j"
- set "num=0"
- ) else if !%%j! neq 0 set num=!%%j!
- )
- set /a "result+=content+num
- if defined stry (
- set "s1=!stry!fedcba9876543210"
- set "s2=!result!fedcba9876543210"
- set /a "len=0x!s1:~16,1!-0x!s2:~16,1!"
- for /f %%i in ("!len!") do echo !str! "!stry:~,%%i!!result!"
- ) else echo;!str! !result!
- pause
复制代码
作者: Ru_Evan 时间: 2024-3-31 19:57
本帖最后由 Ru_Evan 于 2024-3-31 20:01 编辑
之前写了一个,不知道放哪了。。步骤是将中文数字以亿、万分割得到三组中文数字,再分别处理三组中文数字转换成阿拉伯数字,最后三组阿拉伯数字相加而得。
作者: Ru_Evan 时间: 2024-3-31 19:58
本帖最后由 Ru_Evan 于 2024-3-31 20:02 编辑
。。。。。
作者: Five66 时间: 2024-3-31 20:52
本帖最后由 Five66 于 2024-3-31 23:58 编辑
回复 19# terse
犯傻了 , 已编辑
作者: terse 时间: 2024-4-1 06:41
回复 22# Five66
已编辑
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |