v1版本:
; v1版本
; MsgBox, % GetFirstChar("你好呀") ; 输出“NHY”;
; 功能: 中文转为拼音首字母,非中文保持不变
; 备注: 在 AutoHotkey Unicode 中运行
GetFirstChar(str)
{
static nothing := VarSetCapacity(var, 2)
static array := [ [-20319,-20284,"A"], [-20283,-19776,"B"], [-19775,-19219,"C"], [-19218,-18711,"D"], [-18710,-18527,"E"], [-18526,-18240,"F"], [-18239,-17923,"G"], [-17922,-17418,"H"], [-17417,-16475,"J"], [-16474,-16213,"K"], [-16212,-15641,"L"], [-15640,-15166,"M"], [-15165,-14923,"N"], [-14922,-14915,"O"], [-14914,-14631,"P"], [-14630,-14150,"Q"], [-14149,-14091,"R"], [-14090,-13319,"S"], [-13318,-12839,"T"], [-12838,-12557,"W"], [-12556,-11848,"X"], [-11847,-11056,"Y"], [-11055,-10247,"Z"] ]
; 如果不包含中文字符,则直接返回原字符
if !RegExMatch(str, "[^\x{00}-\x{ff}]")
Return str
Loop, Parse, str
{
if ( Asc(A_LoopField) >= 0x2E80 and Asc(A_LoopField) <= 0x9FFF )
{
StrPut(A_LoopField, &var, "CP936")
nGBKCode := (NumGet(var, 0, "UChar") << 8) + NumGet(var, 1, "UChar") - 65536
For i, a in array
if nGBKCode between % a.1 and % a.2
{
out .= a.3
Break
}
}
else
out .= A_LoopField
}
Return out
}
v2版本:
; v2版本
; MsgBox(ChineseFirstChar("你好呀")) ;输出 “你好呀”
; return
ChineseFirstChar(str)
{
static bufferObj := Buffer(2)
VarSetStrCapacity(&var, 2)
static array := [[-20319, -20284, "A"], [-20283, -19776, "B"], [-19775, -19219, "C"], [-19218, -18711, "D"], [-18710, -18527, "E"], [-18526, -18240, "F"], [-18239, -17923, "G"], [-17922, -17418, "H"], [-17417, -16475, "J"], [-16474, -16213, "K"], [-16212, -15641, "L"], [-15640, -15166, "M"], [-15165, -14923, "N"], [-14922, -14915, "O"], [-14914, -14631, "P"], [-14630, -14150, "Q"], [-14149, -14091, "R"], [-14090, -13319, "S"], [-13318, -12839, "T"], [-12838, -12557, "W"], [-12556, -11848, "X"], [-11847, -11056, "Y"], [-11055, -10247, "Z"]]
; 如果不包含中文字符,则直接返回原字符
if !RegExMatch(str, "[^\x{00}-\x{ff}]")
return str
loop parse, str
{
if (Ord(A_LoopField) >= 0x2E80 and Ord(A_LoopField) <= 0x9FFF)
{
StrPut(A_LoopField, bufferObj, "CP936")
nGBKCode := (NumGet(bufferObj, 0, "UChar") << 8) + NumGet(bufferObj, 1, "UChar") - 65536
for item in array {
if (nGBKCode >= item[1] and nGBKCode <= item[2]) {
out .= item[3]
Break
}
}
}
else
out .= A_LoopField
}
return out
}
不适用多音字
利用GBK编码的排列顺序快速获得首字母,不适合多音字
这个必需回复一下
unit PYIndexUnit; {*******************************************************} { 汉字–>拼音声母处理 v4.0 } { Developed by cyw(QQ: 26890954) } { 2013.9.13 All Right Reserved. } {*******************************************************} { 一、特点: 1、支持多音字,支持所有中国汉字(共20902个),包括难字、生僻字、广东白话字、繁体字等所有计算机能显示的全部汉字。 例如:镕、啱、揾、叻、嘅、咁、門、長、發財、車、冇乜嘢。 2、同时支持Unicode和ANSI字符集。 3、支持Delphi6至DelphiXE系列的所有Delphi版本(最后一次测试是XE4)。 二、实现原理(Unicode): 1、根据汉字的编码规则,汉字在Unicode的编码范围为$4E00至$9FA5(即:19968至40869, 共20902个汉字)。 2、对中国汉字字库中的每个汉字,扫描从互联网下载的较完整的拼音字库,找到每个汉字的全拼拼音 (包括多音,一个汉字最多4种读音),并获取每个读音的声母(首字母), 生成汉字声母字典文件。 3、把声母字典文件中每个汉字的声母,按汉字字库的Unicode编码规则全部串在一起,由于一个汉字最多3种读音(有4种以上读音的 仅有”竓qfzygs, 竕sfzyg, 竡ygsb”三个生僻字, 仅取前三个读音),为每个汉字预留3个字节空间,生成Unicode汉字声母表, 如本单元所定义的PartUnicode常量。 4、查找原理:要查找一个汉字在声母表中的对应位置,应使用以下公式计算得: 汉字声母索引 = (汉字Unicode编码 – 19968) * 3 + 1; //其中19968是指Unicode字符集中的第一个汉字位置; 3表示每个汉字预留的3个字节空间 三、实现原理(ANSI): 1、根据汉字的编码规则,第一字节为区码(纵向),第二字节为位码(横向), 第一字节的范围是129-254,共126种,其中161-169段存放各种标点符号,254段为无效汉字,真正有效段为129-160,170-253,共116种。 第二字节的范围是64-254,其中127段为分隔符,不存在任何内容,真正有效段为64-126,128-254,共190种。 排除无效字符及标点符号后,有效的汉字库分为三部分: 1)第一部分(区:129-160 位:64-254[除127]) 32*190 =6080 2)第二部分(区:170-253 位:64-160[除127], 区253位156-160留空) 84*96-5=8059 3)第三部分(区:176-247 位:161-254, 区215位250-254留空) 72*94-5=6763 合计: 20902个汉字 2、按以上规则可生成三个部分的中国汉字字库,每个区码一行,每个位码一列。 3、同二(2)。 4、同二(3),如本单元所定义的Part1..Part3常量。 5、查找原理:要查找一个汉字在声母表中的对应位置,应使用以下公式计算得: 汉字声母索引 = ((汉字区码 – 段落起始区码) * 位码长度 + 汉字位码 – 段落起始位码) * 3 + 1; //其中3表示每个汉字预留的3个字节空间 如汉字“啊”,其区位码分别是(176,161),根据上述第1点所定义,属于第三部分汉字,理应在常量Part3中查找, 由于第三部分的位码范围是161-254,横向长度是94,即一行(一个区)有94个汉字,所以“啊”在Part3中的位置应该是: ((176-176) * 94 + 161 – 161) * 3 + 1 = 1,即Part3[1] = ‘a’; 四、更新历史: 1、10.9.8 由于全拼输入法的拼音库太过全面,有部分多音字的第一个拼音却不是常用的拼音,导致汉字转声母有时不准确, 决定抛弃全拼输入法的拼音库,改为采用从互联网下载的较完整的拼音字库,重新生成汉字声母表。 2、10.12.27 上一次更新时是在Excel中编辑文件的,在Excel内替换右括号”)”为空时,”Jun1)”替换后会变成”1-Jun”, Excel的奇怪现象,导致”军”字的声母变成数字”1″,类似的情况还有很多。本次更新全面修正此类问题,并且经检测发现99.9%以上的 多音字最多只有三个读音,仅”竓qfzygs, 竕sfzyg, 竡ygsb”三个生僻字有4种以上读音, 故声母表全部由4个字节改为预留3个字节, 上述三个僻字仅截取前三个读音的声母。 3、12.2.14 之前的版本按常用程度分为五个级别,但却漏了(区:170-175 位:64-160)一段汉字,合计漏了6*96=576个汉字未处理。今改为按汉字编码 分布规则,划分为三个部分(三段),共计20902个汉字,是迄今为止史上最完整的汉字字库。据此生成的Part1、Part2、Part3三个声母 常量也是最完整的汉字声母表。另外,从该版本起,开始支持Delphi2007-DelphiXE系列。 4、13.9.13 针对Unicode的编码规则,生成全新的Unicode原生汉字声母表,放弃以前把String转换为AnsiString的方法,由于少了转换步骤,所以理论上 在Delphi2009(或更高版本)时算法速度更优更快。同时使用编译指令兼容Delphi6-2007的非UniCode开发环境,这部分保留以前的算法。 } interface uses SysUtils; //————————— 声明段 ——————————————- //获取指定汉字的拼音索引字母,如:汉 = h。多音字返回多个声母,如:行 = hx function GetPYIndex(const OneWord: String; const OnlyOne: Boolean = False): String; //获取指定字符串的拼音索引字母(多音字总是取第一个音的声母)。如:中山大学 = zsdx function GetStrPYIndex(const Str: String): String; //获取字符串Str中与拼音声母字符串PYStr匹配的起始位置。如:PosPY(‘zsdx’,’我来自中山大学’),在Unicode环境中返回4,非Unicode环境返回7 function PosPY(const PYStr, Str: String): Integer; //判断字符串Str的拼音声母是否全部与PYStr相同。如:SamePY(‘zsdx’, ‘中山大学’) = True function SamePY(const PYStr, Str: String): Boolean; //获取字符串Str中拼音声母串与字符串SubStr拼音声母串匹配的起始位置。如:PosTextPY(‘纵声大笑’, ‘我来自中山大学’),在Unicode环境中返回4,非Unicode环境返回7 function PosTextPY(const SubStr, Str: String): Integer; //判断字符串Str的拼音声母是否全部与字符串SubStr的拼音声母相同。如:SameTextPY(‘纵声大笑’, ‘中山大学’) = True function SameTextPY(const SubStr, Str: String): Boolean; //—————————- 实现段 —————————————— implementation const MaxPYLength = 3; //最大的拼音声母个数 {$IFDEF UNICODE} //Unicode汉字声母表 $4E00至$9FA5(即:19968至40869, 共20902个) PartUnicode = ‘y dz k q s x n wm z s s x j bf y m g c c z qj p s s q b y c d s c d q l d y l y b s s j g y qp z j j f g c c l z zd n w d w z jd l j p f y ya n n j j t my y n z w z h f ly z p p ‘ +’q h g cs cs y y n mn j q y x x g d n n s n s j n j n s n n m l n r x y f s n gq n n n n qg z gjqg l l y j l n y z s s e c y k y y h q w j s s g g y x y q y jq t w k t j h y c ‘