好吧,也许你没有兴趣,这样的话我贴完代码后也把问题修改为
[SOLVED]。
下面这种方案可满足主题中所述各种情况:
- 支持多音字;
- 支持全拼、简拼或可部分全拼部分简拼;
- 若存在匹配,能正确返回目标字符串中的匹配位置;
下面的代码仅为演示这种方案,可能有些边际情况仍需进一步处理(如需保持某些特殊字符为原义),欢迎自行调整:
Code: Select all
FileRead, Uni2Pinyin, f:\Uni2Pinyin.mb
/* Tab 分隔的多列文本,首列为汉字的 Unicode 编码,后续为拼音。如:
4E07 wan mo
*/
prase := "keyyx" ; 用户输入的字符串。
ChnStr := "哦,AutoHotkey银行吗?是基金会。" ; 待判断的字符串。
MsgBox, % Str2Pinyin(ChnStr)
PraseLen := StrLen(prase)
Loop, % StrLen(ChnStr) - StrLen(prase) + 1 ; 比较目标字符串中是否存在用户输入字符串的匹配。
{
Pos := RegexMatch(prase, Str2Pinyin(SubStr(ChnStr, A_Index, PraseLen)))
If (Pos = 1)
MsgBox, The string was found at position %A_Index%.
}
Pause
Str2Pinyin(s)
{
Global Uni2Pinyin
Loop, Parse, s
{
SetFormat, Integer, HEX
ChrCode := Asc(A_LoopField)
SetFormat, Integer, D
If ChrCode between 0x3007 and 0x9FA5
{
If RegexMatch(Uni2Pinyin, "im`n)^" SubStr(ChrCode, 3) "\t(.+)$", PinyinGroup)
{
ArrPinyin := StrSplit(PinyinGroup1, A_Tab)
If (ArrPinyin.MaxIndex() = 1) ; 单音字
If (StrLen(ArrPinyin[1]) = 1)
PinyinStr .= ArrPinyin[1]
else
PinyinStr .= SubStr(ArrPinyin[1], 1, 1) "(" SubStr(ArrPinyin[1], 2) ")?"
else ; 多音字
{
Needle := ""
Loop, % ArrPinyin.MaxIndex() - 1
{
if (StrLen(ArrPinyin[A_Index]) = 1)
Needle .= ArrPinyin[A_Index] "|"
else
Needle .= SubStr(ArrPinyin[A_Index], 1, 1) "(" SubStr(ArrPinyin[A_Index], 2) ")?|"
}
if (StrLen(ArrPinyin[ArrPinyin.MaxIndex()]) = 1)
Needle .= ArrPinyin[ArrPinyin.MaxIndex()]
else
Needle .= SubStr(ArrPinyin[ArrPinyin.MaxIndex()], 1, 1) "(" SubStr(ArrPinyin[ArrPinyin.MaxIndex()], 2) ")?"
PinyinStr .= "(" Needle ")"
}
}
else
{
PinyinStr .= A_LoopField
}
}
else ; 非汉字字符
{
PinyinStr .= A_LoopField ; 一些特殊字符可能需要保持原义(这里未作处理)。
}
}
Return, PinyinStr
}
其中,Uni2Pinyin.mb 来自于
Pinyin table for Unicode,进行了两方面处理(结构请参阅代码中所示):
对于 aamii 的方案,我考虑过,支持简拼也不错了,而且效率应该比刚才的代码更好。