function ChangeChineseToPY(aChinese: string; aIsCapital: Boolean; var oPYStr: string): string; //汉字转换成拼音码 function GetPYIndexChar(hzchar: string): Char; begin case Word(hzchar[1]) shl 8 + Word(hzchar[2]) of $B0A1..$B0C4: Result := 'a'; $B0C5..$B2C0: Result := 'b'; $B2C1..$B4ED: Result := 'c'; $B4EE..$B6E9: Result := 'd'; $B6EA..$B7A1: Result := 'e'; $B7A2..$B8C0: Result := 'f'; $B8C1..$B9FD: Result := 'g'; $B9FE..$BBF6: Result := 'h'; $BBF7..$BFA5: Result := 'j'; $BFA6..$C0AB: Result := 'k'; $C0AC..$C2E7: Result := 'l'; $C2E8..$C4C2: Result := 'm'; $C4C3..$C5B5: Result := 'n'; $C5B6..$C5BD: Result := 'o'; $C5BE..$C6D9: Result := 'p'; $C6DA..$C8BA: Result := 'q'; $C8BB..$C8F5: Result := 'r'; $C8F6..$CBF9: Result := 's'; $CBFA..$CDD9: Result := 't'; $CDDA..$CEF3: Result := 'w'; $CEF4..$D188: Result := 'x'; $D1B9..$D4D0: Result := 'y'; $D4D1..$D7F9: Result := 'z'; else Result := Char(32); end; end;var i: Integer; C: Char; begin oPYStr := ''; i := 1; while i <= Length(aChinese) do begin if aChinese[i] <= Chr(127) then begin if aIsCapital then oPYStr := oPYStr + UpCase(aChinese[i]) else oPYStr := oPYStr + aChinese[i]; i := i + 1; end else begin C := GetPYIndexChar(Copy(aChinese, i, 2)); if C <> Char(32) then if aIsCapital then oPYStr := oPYStr + UpCase(C) else oPYStr := oPYStr + C; i := i + 2; end; end; end;
function PY(S: string): string; var I: Integer; Key: Word; begin Result := ''; I := 1; while I <= Length(S) do begin Key := Ord(S[I]) * 256 + Ord(S[I + 1]); Inc(I, 2); case Key of $B0A1..$B0C4: Result := Result + 'A'; $B0C5..$B2C0: Result := Result + 'B'; $B2C1..$B4ED: Result := Result + 'C'; $B4EE..$B6E9: Result := Result + 'D'; $B6EA..$B7A1: Result := Result + 'E'; $B7A2..$B8C0: Result := Result + 'F'; $B8C1..$B9FD: Result := Result + 'G'; $B9FE..$BBF6: Result := Result + 'H'; $BBF7..$BFA5: Result := Result + 'J'; $BFA6..$C0AB: Result := Result + 'K'; $C0AC..$C2E7: Result := Result + 'L'; $C2E8..$C4C2: Result := Result + 'M'; $C4C3..$C5B5: Result := Result + 'N'; $C5B6..$C5BD: Result := Result + 'O'; $C5BE..$C6D9: Result := Result + 'P'; $C6DA..$C8BA: Result := Result + 'Q'; $C8BB..$C8F5: Result := Result + 'R'; $C8F6..$CBF9: Result := Result + 'S'; $CBFA..$CDD9: Result := Result + 'T'; $CDDA..$CEF3: Result := Result + 'W'; $CEF4..$D188: Result := Result + 'X'; $D1B9..$D4D0: Result := Result + 'Y'; $D4D1..$D7F9: Result := Result + 'Z'; else Result := Result + '?'; end; end; end;
function ChangeChineseToPY(aChinese: string; aIsCapital: Boolean; var oPYStr: string): string; //汉字转换成拼音码 function GetPYIndexChar(hzchar: string): Char; begin case Word(hzchar[1]) shl 8 + Word(hzchar[2]) of $B0A1..$B0C4: Result := 'a'; $B0C5..$B2C0: Result := 'b'; $B2C1..$B4ED: Result := 'c'; $B4EE..$B6E9: Result := 'd'; $B6EA..$B7A1: Result := 'e'; $B7A2..$B8C0: Result := 'f'; $B8C1..$B9FD: Result := 'g'; $B9FE..$BBF6: Result := 'h'; $BBF7..$BFA5: Result := 'j'; $BFA6..$C0AB: Result := 'k'; $C0AC..$C2E7: Result := 'l'; $C2E8..$C4C2: Result := 'm'; $C4C3..$C5B5: Result := 'n'; $C5B6..$C5BD: Result := 'o'; $C5BE..$C6D9: Result := 'p'; $C6DA..$C8BA: Result := 'q'; $C8BB..$C8F5: Result := 'r'; $C8F6..$CBF9: Result := 's'; $CBFA..$CDD9: Result := 't'; $CDDA..$CEF3: Result := 'w'; $CEF4..$D188: Result := 'x'; $D1B9..$D4D0: Result := 'y'; $D4D1..$D7F9: Result := 'z'; else Result := Char(32); end; end;var i: Integer; C: Char; begin oPYStr := ''; i := 1; while i <= Length(aChinese) do begin if aChinese[i] <= Chr(127) then begin if aIsCapital then oPYStr := oPYStr + UpCase(aChinese[i]) else oPYStr := oPYStr + aChinese[i]; i := i + 1; end else begin C := GetPYIndexChar(Copy(aChinese, i, 2)); if C <> Char(32) then if aIsCapital then oPYStr := oPYStr + UpCase(C) else oPYStr := oPYStr + C; i := i + 2; end; end; end;
如果汉字字符串中含有字母和数字怎么办?例如:’联想昭阳 E420‘ 转化为'LXZY E420'
Function GetPYM(MyStr:String):WideString; Var I,N:Integer; Stemp:String; AHZ:String; NowHZ,NowPY:String; AllLen,NowPos:Integer; Begin AllLen:=Length(HZPYM); Stemp:=''; N:=Length(MyStr); I:=1; While I<=N DO Begin If ORD(MyStr[I])<=127 Then Begin //是字母、数字、符号 Stemp:=Stemp+MyStr[I]; Inc(I); End Else Begin AHZ:=MyStr[I]+MyStr[I+1]; Inc(I,2); NowPos:=1; While NowPos<=AllLen Do Begin If Ord(HZPYM[NowPos])<=127 Then Begin NowPY:=HZPYM[NowPos]; Inc(NowPos); End Else Begin NowHZ:=HZPYM[NowPos]+HZPYM[NowPos+1]; Inc(NowPos,2); End; If AHZ=NowHZ Then Stemp:=Stemp+NowPY; End; End; End; Result:=UpperCase(Stemp); End;
string): string; //汉字转换成拼音码
function GetPYIndexChar(hzchar: string): Char;
begin
case Word(hzchar[1]) shl 8 + Word(hzchar[2]) of
$B0A1..$B0C4: Result := 'a';
$B0C5..$B2C0: Result := 'b';
$B2C1..$B4ED: Result := 'c';
$B4EE..$B6E9: Result := 'd';
$B6EA..$B7A1: Result := 'e';
$B7A2..$B8C0: Result := 'f';
$B8C1..$B9FD: Result := 'g';
$B9FE..$BBF6: Result := 'h';
$BBF7..$BFA5: Result := 'j';
$BFA6..$C0AB: Result := 'k';
$C0AC..$C2E7: Result := 'l';
$C2E8..$C4C2: Result := 'm';
$C4C3..$C5B5: Result := 'n';
$C5B6..$C5BD: Result := 'o';
$C5BE..$C6D9: Result := 'p';
$C6DA..$C8BA: Result := 'q';
$C8BB..$C8F5: Result := 'r';
$C8F6..$CBF9: Result := 's';
$CBFA..$CDD9: Result := 't';
$CDDA..$CEF3: Result := 'w';
$CEF4..$D188: Result := 'x';
$D1B9..$D4D0: Result := 'y';
$D4D1..$D7F9: Result := 'z';
else
Result := Char(32);
end;
end;var
i: Integer;
C: Char;
begin
oPYStr := '';
i := 1;
while i <= Length(aChinese) do
begin
if aChinese[i] <= Chr(127) then
begin
if aIsCapital then
oPYStr := oPYStr + UpCase(aChinese[i])
else
oPYStr := oPYStr + aChinese[i];
i := i + 1;
end
else
begin
C := GetPYIndexChar(Copy(aChinese, i, 2));
if C <> Char(32) then
if aIsCapital then
oPYStr := oPYStr + UpCase(C)
else
oPYStr := oPYStr + C;
i := i + 2;
end;
end;
end;
var
I: Integer;
Key: Word;
begin
Result := '';
I := 1;
while I <= Length(S) do
begin
Key := Ord(S[I]) * 256 + Ord(S[I + 1]);
Inc(I, 2);
case Key of
$B0A1..$B0C4: Result := Result + 'A';
$B0C5..$B2C0: Result := Result + 'B';
$B2C1..$B4ED: Result := Result + 'C';
$B4EE..$B6E9: Result := Result + 'D';
$B6EA..$B7A1: Result := Result + 'E';
$B7A2..$B8C0: Result := Result + 'F';
$B8C1..$B9FD: Result := Result + 'G';
$B9FE..$BBF6: Result := Result + 'H';
$BBF7..$BFA5: Result := Result + 'J';
$BFA6..$C0AB: Result := Result + 'K';
$C0AC..$C2E7: Result := Result + 'L';
$C2E8..$C4C2: Result := Result + 'M';
$C4C3..$C5B5: Result := Result + 'N';
$C5B6..$C5BD: Result := Result + 'O';
$C5BE..$C6D9: Result := Result + 'P';
$C6DA..$C8BA: Result := Result + 'Q';
$C8BB..$C8F5: Result := Result + 'R';
$C8F6..$CBF9: Result := Result + 'S';
$CBFA..$CDD9: Result := Result + 'T';
$CDDA..$CEF3: Result := Result + 'W';
$CEF4..$D188: Result := Result + 'X';
$D1B9..$D4D0: Result := Result + 'Y';
$D4D1..$D7F9: Result := Result + 'Z';
else
Result := Result + '?';
end;
end;
end;
你的函数怎么调用啊??
如果操作的汉字是次常用字,内码是按笔画部首排序的,怎么办?
如果是罕用字,在GBK中的,怎么办?
其他如GB18030中的汉字,更难办了吧?我觉得,好的做法是利用windows自己的功能,windows2000等早就具备汉字按拼音、笔画等排序的功能了。调用lstrcpm等函数就可以了。
可以针对26个字母,取得每个字母的第一个汉字,比如a是吖,b是八等,然后让要操作的字与这些汉字逐次比较就能决定是哪个拼音了。
Windows能保证你这样得到的比较次序是按照拼音和笔画排序的。
简体中文Windows安装默认按照拼音排序,但也可以通过控制面版中更改为笔画排序、注音字母排序等。也可以在程序中动态设置。
string): string; //汉字转换成拼音码
function GetPYIndexChar(hzchar: string): Char;
begin
case Word(hzchar[1]) shl 8 + Word(hzchar[2]) of
$B0A1..$B0C4: Result := 'a';
$B0C5..$B2C0: Result := 'b';
$B2C1..$B4ED: Result := 'c';
$B4EE..$B6E9: Result := 'd';
$B6EA..$B7A1: Result := 'e';
$B7A2..$B8C0: Result := 'f';
$B8C1..$B9FD: Result := 'g';
$B9FE..$BBF6: Result := 'h';
$BBF7..$BFA5: Result := 'j';
$BFA6..$C0AB: Result := 'k';
$C0AC..$C2E7: Result := 'l';
$C2E8..$C4C2: Result := 'm';
$C4C3..$C5B5: Result := 'n';
$C5B6..$C5BD: Result := 'o';
$C5BE..$C6D9: Result := 'p';
$C6DA..$C8BA: Result := 'q';
$C8BB..$C8F5: Result := 'r';
$C8F6..$CBF9: Result := 's';
$CBFA..$CDD9: Result := 't';
$CDDA..$CEF3: Result := 'w';
$CEF4..$D188: Result := 'x';
$D1B9..$D4D0: Result := 'y';
$D4D1..$D7F9: Result := 'z';
else
Result := Char(32);
end;
end;var
i: Integer;
C: Char;
begin
oPYStr := '';
i := 1;
while i <= Length(aChinese) do
begin
if aChinese[i] <= Chr(127) then
begin
if aIsCapital then
oPYStr := oPYStr + UpCase(aChinese[i])
else
oPYStr := oPYStr + aChinese[i];
i := i + 1;
end
else
begin
C := GetPYIndexChar(Copy(aChinese, i, 2));
if C <> Char(32) then
if aIsCapital then
oPYStr := oPYStr + UpCase(C)
else
oPYStr := oPYStr + C;
i := i + 2;
end;
end;
end;
Var I,N:Integer;
Stemp:String;
AHZ:String; NowHZ,NowPY:String;
AllLen,NowPos:Integer;
Begin
AllLen:=Length(HZPYM); Stemp:='';
N:=Length(MyStr);
I:=1;
While I<=N DO
Begin
If ORD(MyStr[I])<=127 Then
Begin
//是字母、数字、符号
Stemp:=Stemp+MyStr[I];
Inc(I);
End
Else
Begin
AHZ:=MyStr[I]+MyStr[I+1];
Inc(I,2); NowPos:=1;
While NowPos<=AllLen Do
Begin
If Ord(HZPYM[NowPos])<=127 Then
Begin
NowPY:=HZPYM[NowPos];
Inc(NowPos);
End
Else
Begin
NowHZ:=HZPYM[NowPos]+HZPYM[NowPos+1];
Inc(NowPos,2);
End; If AHZ=NowHZ Then
Stemp:=Stemp+NowPY;
End;
End;
End;
Result:=UpperCase(Stemp);
End;
我前面帖子说过了,楼上几位给出的代码,只适用于GB国标码中的前面部分,即3800多个汉字之间的排序,超出这个范围的汉字,那就全乱套了。win9x,win2000开始支持gbk字库,有大约21000多个吧,楼上这些代码如何处理这些汉字?
所以,我决定自己写个能统吃这些汉字的给出拼音首字母的代码。大家等待吧。
抱歉的是,我用vc写的,改写成delphi也不麻烦。
这个函数能将一个字符串中的汉字转换成对应拼音的第一个字母,不是汉字则不转换。
适用的汉字包括GBK中所有汉字。如果系统中安装有GB18030大字符集支持,估计其中的汉字也可以支持,但我没有测试过。只要修改对照表内容和MAKELCID中的几个常数,就能变成按照笔画笔顺排序。
/*
*存放每个字母和对应的第一个汉字,“字母汉字对”
*/
struct pyPair
{
char chPy;
char *chHz;
};/*
*查字符映射表得到的,仅做测验用
*/
pyPair pyTable[]=
{
{'A',"阿"},
{'B',"八"},
{'C',"擦"},
{'D',"搭"},
{'E',"屙"},
{'F',"贬"},
{'G',"噶"},
{'H',"哈"},
//{'I',""},
{'J',"击"},
{'K',"喀"},
{'L',"垃"},
{'M',"妈"},
{'N',"拿"},
{'O',"哦"},
{'P',"吧"},
{'Q',"畸"},
{'R',"然"},
{'S',"撒"},
{'T',"塌"},
//{'U',""},
//{'V',""},
{'W',"挖"},
{'X',"栖"},
{'Y',"压"},
{'Z',"匝"},
{'[',"坐"},
};HRESULT FirstPinyinOfChinese(const CString strChinese, CString *strPinyin)
{
char chPy; //每个汉字的拼音结果
int iCmp; //每次调用CompareString的结果
int p=0; //索引号,指向当前处理的汉字或字母
pyPair *ppyTable; //指向当前比对的“字母汉字对结构” /*
* 在简体中文代码页进行比较,缺省排序规则,也就是汉语拼音,其他有
* SORT_CHINESE_PRC :汉字笔画
* SORT_CHINESE_PRCP :汉字拼音
* SORT_CHINESE_UNICODE :汉字Unicode
*/
DWORD lcid = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT); int iLen = strChinese.GetLength(); *strPinyin = ""; while(p < iLen) //处理整个字符串中的字符
{
if(!isascii(strChinese[p]) && p<iLen-1) //如果不是ascii字符,就认为是汉字
{
chPy = '_';
ppyTable = pyTable;
while(ppyTable->chPy <= 'Z')
{
iCmp = CompareString(lcid, 0, (LPTSTR)(LPCTSTR)strChinese + p, 2, ppyTable->chHz, -1);
// 本来想用lstrcmp()的,简单,但还是CompareString好,能指定代码页。
if(0 == iCmp)
{
*strPinyin = "Error in PinyinImp.cpp::FirstPinyinOfChinese()::CompareString()!";
// 调用CompareString发生错误。这里立即返回。也可不返回,忽略,处理下一字符。
return S_FALSE;
}
if(CSTR_GREATER_THAN == iCmp || CSTR_EQUAL == iCmp)
{
// 未找到相应拼音,前进到下一个结构
chPy = ppyTable->chPy;
ppyTable++;
}
if(CSTR_LESS_THAN == iCmp) // 找到了
{
break;
}
} // end of while ppyTable->chPy<='Z'
p+=2;
}
else //如果是ascii字符,就不作转换
{
chPy = strChinese[p];
p++;
}
*strPinyin += chPy;
} // end of while p
return S_OK;
}