本帖最后由 CrLf 于 2011-11-27 12:19 编辑
if 的排序规则一直让人困扰,它既不遵从 nls 代码页文件的字符顺序,也不遵从 gbk 或者 unicode 的编码顺序,昨天从个人收藏中翻出一份“汉字编码.txt”(某位大师给的,一直没用上,差点忘了...),忽然想起 if 的字符排序是否和字典里的拼音顺序吻合?这个说法是可以解释得了英文字母为何会出现 A lss b 的现象的,那放在汉字环境中是否也成立呢?
于是着手测试,小规模手工粗筛结果初步证明了这一点(比如 if 啊 lss 吧 if 吧 lss 嚓 echo 啊 lss 吧 lss 嚓)。
看来颇有希望,而要进行缜密的验证,需要把“汉字编码.txt”处理成易于解读的格式,于是进行了为时 N 小时的痛苦处理(愿意看处理全程的筒子可以看 2 楼)...
在处理“汉字编码.txt”的过程中,通过对字符顺序的比较,证明 if 对汉字进行字符比较时确实是依照拼音顺序排序的,于是顺便写了一个汉字转拼音的小脚本(不判断多音字):
所用到的简表“汉字拼音与排序.txt”(就是刚生成的 11.txt,规格是“拼音a的第一个汉字 a 拼音ai的第一个汉字 ai 拼音an的第一个汉字...”):- 吖 a 埃 ai 氨 an 肮 ang 凹 ao 芭 ba 白 bai 班 ban 邦 bang 苞 bao 杯 bei 奔 ben 崩 beng 逼 bi 边 bian 标 biao 憋 bie 彬 bin 冰 bing 玻 bo 卜 bu 擦 ca 猜 cai 参 can 苍 cang 操 cao 厕 ce 岑 cen 层 ceng 叉 cha 拆 chai 掺 chan 猖 chang 朝 chao 车 che 臣 chen 城 cheng 痴 chi 虫 chong 畴 chou 厨 chu 搋 chuai 穿 chuan 窗 chuang 炊 chui 椿 chun 辍 chuo 茨 ci 葱 cong 凑 cou 粗 cu 蹿 cuan 崔 cui 村 cun 磋 cuo 搭 da 呆 dai 担 dan 当 dang 刀 dao 得 de 灯 deng 低 di 嗲 dia 掂 dian 叼 diao 爹 die 丁 ding 丢 diu 东 dong 都 dou 督 du 端 duan 堆 dui 吨 dun 哆 duo 峨 e 诶 ei 恩 en 儿 er 发 fa 帆 fan 坊 fang 非 fei 芬 fen 丰 feng 佛 fo 缶 fou 夫 fu 嘎 ga 该 gai 甘 gan 冈 gang 皋 gao 哥 ge 给 gei 根 gen 耕 geng 工 gong 勾 gou 菇 gu 瓜 gua 乖 guai 关 guan 光 guang 规 gui 辊 gun 郭 guo 哈 ha 孩 hai 酣 han 夯 hang 壕 hao 呵 he 黑 hei 痕 hen 亨 heng 轰 hong 侯 hou 乎 hu 花 hua 徊 huai 欢 huan 荒 huang 灰 hui 昏 hun 锪 huo 击 ji 枷 jia 歼 jian 姜 jiang 椒 jiao 接 jie 巾 jin 荆 jing 炯 jiong 究 jiu 拘 ju 捐 juan 撅 jv 均 jun 咖 ka 开 kai 刊 kan 康 kang 考 kao 苛 ke 肯 ken 坑 keng 空 kong 抠 kou 枯 ku 夸 kua 块 kuai 宽 kuan 匡 kuang 亏 kui 坤 kun 扩 kuo 垃 la 来 lai 婪 lan 琅 lang 捞 lao 乐 le 雷 lei 棱 leng 厘 li 莲 lian 凉 liang 聊 liao 列 lie 林 lin 玲 ling 溜 liu 龙 long 娄 lou 卢 lu 峦 luan 抡 lun 萝 luo 驴 lv 略 lve 妈 ma 埋 mai 馒 man 芒 mang 猫 mao 么 me 玫 mei 门 men 萌 meng 眯 mi 眠 mian 苗 miao 灭 mie 民 min 明 ming 谬 miu 摸 mo 牟 mou 姆 mu 拿 na 乃 nai 男 nan 囊 nang 挠 nao 讷 ne 馁 nei 嫩 nen 能 neng 妮 ni 拈 nian 娘 niang 鸟 niao 捏 nie 您 nin 狞 ning 牛 niu 浓 nong 耨 nou 奴 nu 暖 nuan 挪 nuo 钕 nve 女 nv 噢 o 欧 ou 趴 pa 拍 pai 潘 pan 乓 pang 抛 pao 呸 pei 喷 pen 抨 peng 坯 pi 偏 pian 漂 piao 瞥 pie 拼 pin 乒 ping 坡 po 剖 pou 扑 pu 期 qi 掐 qia 扦 qian 枪 qiang 锹 qiao 切 qie 钦 qin 青 qing 穷 qiong 丘 qiu 区 qu 圈 quan 炔 qv 裙 qun 然 ran 瓤 rang 饶 rao 惹 re 壬 ren 扔 reng 日 ri 戎 rong 柔 rou 茹 ru 阮 ruan 蕊 rui 闰 run 若 ruo 洒 sa 腮 sai 三 san 桑 sang 搔 sao 色 se 森 sen 僧 seng 砂 sha 筛 shai 苫 shan 伤 shang 捎 shao 奢 she 申 shen 生 sheng 失 shi 收 shou 枢 shu 刷 shua 衰 shuai 拴 shuan 双 shuang 谁 shui 吮 shun 说 shuo 斯 si 松 song 搜 sou 苏 su 酸 suan 虽 sui 孙 sun 梭 suo 他 ta 胎 tai 坍 tan 汤 tang 涛 tao 忒 te 腾 teng 剔 ti 天 tian 挑 tiao 贴 tie 厅 ting 通 tong 偷 tou 凸 tu 湍 tuan 推 tui 吞 tun 乇 tuo 挖 wa 歪 wai 弯 wan 汪 wang 威 wei 温 wen 翁 weng 挝 wo 巫 wu 昔 xi 虾 xia 掀 xian 相 xiang 萧 xiao 些 xie 芯 xin 星 xing 凶 xiong 休 xiu 戌 xu 轩 xuan 靴 xv 勋 xun 压 ya 咽 yan 央 yang 腰 yao 椰 ye 一 yi 茵 yin 英 ying 哟 yo 佣 yong 优 you 迂 yu 鸳 yuan 曰 yv 云 yun 匝 za 哉 zai 咱 zan 赃 zang 遭 zao 责 ze 贼 zei 怎 zen 增 zeng 扎 zha 摘 zhai 毡 zhan 章 zhang 招 zhao 遮 zhe 珍 zhen 蒸 zheng 芝 zhi 中 zhong 舟 zhou 珠 zhu 抓 zhua 拽 zhuai 专 zhuan 庄 zhuang 椎 zhui 谆 zhun 拙 zhuo 咨 zi 棕 zong 邹 zou 租 zu 纂 zuan 嘴 zui 尊 zun 昨 zuo
复制代码 实际代码:- @echo off&setlocal enabledelayedexpansion
- set input=汉字转拼音测试
- set /p input=Input:
- for /f "delims=" %%a in (汉字拼音与排序.txt) do (
- for /l %%b in (0 1 8185) do (
- rem 变量最长 8192 字符,减去变量名和空格,input 变量内容最长为 8186 字符
- if "!input:~%%b!" neq "" (
- set py=
- if !input:~%%b! geq 吖 if !input:~%%b! leq 咗 (
- rem 检测是否是汉字,在 nls 表中,汉字的范围是从吖到咗(小~大)
- set str=%%a
- set py=zuo
- for /l %%c in (1 1 402) do (
- rem 表中共有 402 个拼音,故用 402 次循环
- for /f "tokens=1,2,3*" %%d in ("!str!") do (
- if !input:~%%b! geq %%d if !input:~%%b! lss %%f (
- rem 逐个进行字符比较,查找该汉字是在哪个拼音的范围之内 %%d 为下限,%%e 为拼音,%%f 为上限
- set py=%%e&set str=
- )
- if defined str set str=%%f %%g
- rem 当符合条件时清空 str 变量终止循环,减少内层循环次数
- )
- )
- set var=!var! !py!
- )
- if not defined py set "var=!var!!input:~%%b,1!"
- rem 当该字不为表内汉字时,则附加在输出内容中
- )
- )
- echo;!var!
- )<nul
- pause
复制代码 当然也可以作为函数调用,翻译《归去来兮辞》的实例如下:- @echo off&setlocal enabledelayedexpansion
- echo %time%
- for %%a in (汉字转拼音测试:
- " 《归去来兮辞》陶渊明"
- " 归去来兮!田园将芜胡不归?既自以心为形役,奚惆怅而独悲?悟已往之不谏,知来者之可追;实迷途其未远,觉今是而昨非。舟遥遥以轻飏,风飘飘而吹衣。问征夫以前路,恨晨光之熹微。"
- " 乃瞻衡宇,载欣载奔。僮仆欢迎,稚子候门。三径就荒,松菊犹存。携幼入室,有酒盈樽。引壶觞以自酌,眄庭柯以怡颜。倚南窗以寄傲,审容膝之易安。园日涉以成趣,门虽设而常关。策扶老以流憩,时矫首而遐观。云无心以出岫,鸟倦飞而知还。景翳翳以将入,抚孤松而盘桓。"
- " 归去来兮!请息交以绝游。世与我而相违,复驾言兮焉求?悦亲戚之情话,乐琴书以消忧。农人告余以春及,将有事于西畴。或命巾车,或棹孤舟。既窈窕以寻壑,亦崎岖而经丘。木欣欣以向荣,泉涓涓而始流。善万物之得时,感吾生之行休。"
- " 已矣乎!寓形宇内复几时,曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑! "
- ) do call :hz2py %%a&echo;
- echo %time%
- pause
- :hz2py
- setlocal enabledelayedexpansion
- set "input=%~1"
- for /f "delims=" %%a in (汉字拼音与排序.txt) do (
- for /l %%b in (0 1 8185) do (
- if "!input:~%%b!" neq "" (
- set py=
- if !input:~%%b! geq 吖 if !input:~%%b! leq 咗 (
- set str=%%a
- set py=zuo
- for /l %%c in (1 1 402) do (
- for /f "tokens=1,2,3*" %%d in ("!str!") do (
- if !input:~%%b! geq %%d if !input:~%%b! lss %%f (
- set py=%%e&set str=
- )
- if defined str set str=%%f %%g
- )
- )
- set var=!var! !py!
- )
- if not defined py set "var=!var!!input:~%%b,1!"
- )
- )
- echo;!var!
- )<nul
- endlocal
复制代码 可以看到,利用 if 字符判断,成功地将汉字转换成了拼音,虽然无法判断多音字,但是已经证明了 if 的字符比较在碰到文字(汉字、英文)时是依照字典顺序进行排列的,可以确定的是,if 比较肯定是查表的,而且系统中也存在一个类似 nls 的“字典”,只是其中的语言文字是按照音标顺序排列的。
注:后来证明,排序方式是由区域语言设置来设置的,而保存汉字拼音具体顺序的字典则是 system32 文件夹下的 .nls 文件。(nls 相关内容详见 5 楼链接) |