【已解决】如何判断一个字符串匹配另一个含中文字符串的一部分

遇到了问题?请先进行搜索(中文和英文),然后在此提问

Moderators: tmplinshi, arcticir

User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

【已解决】如何判断一个字符串匹配另一个含中文字符串的一部分

14 Aug 2014, 22:02

标题的描述可能不准确,本问题来自 http://ahkscript.org/boards/viewtopic.p ... 1629#p9827 中的两个回复:
aamii wrote:实际应用中,我们需要用到多音字,比如 ”行走” XZ,”银行” YH。

主要是反过来查询的时候,让YH能匹配银行,YX也能匹配,像totalcmd上支持的那样。
aamii wrote:反过来查的问题,我现在这么解决:
①、在获取首字母的时候,包含多音字,比如“行走”输出为拼音串:[XH][Z]
②、用正则去匹配上面的串,这样不管你输入的是XZ还是HZ都能有效,查找到”行走“的。

仍然有的问题是:在①中,我当前用的是”汉字拼音首字母“对应表,用查表的方法获取。有没有像tmplishi那样的”方法“获得”多音字“呢?
具体的功能类似 Listary 中,能根据用户输入的字符串判断出目标文件名是否匹配(含有中文时,将其转换为简拼或全拼判断)。
具体要求:
  1. 必须考虑多音字
  2. 若存在匹配,必须返回匹配位置
  3. 对于字母与拼音的匹配,可简拼或全拼,若两者都支持最好

Code: Select all

prase := "keyyx"	; 用户输入的字符串。
ChnStr := "哦,AutoHotkey银行吗?是基金会。"	; 待判断的字符串。
大家有什么思路?
AutoHotkey 学习指南(Beauty of AutoHotkey)
I do not make codes, and only a porter of AutoHotkey: from official to Chinese, from other languages to AutoHotkey, and show AutoHotkey to ordinary users sometimes.
User avatar
RobertL
Posts: 540
Joined: 18 Jan 2014, 01:14
Location: China

Re: 如何判断一个字符串与另一个含中文字符串匹配

15 Aug 2014, 06:18

群里讨论过(有过程,无总结,无记录),如果已经有字-拼音(含多音字)对照表,那就用aamii的方法呗..
但他的问题是如何获取包含多音字的对照表,好像有这个表。
我为人人,人人为己?
User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

Re: 如何判断一个字符串匹配另一个含中文字符串的一部分

16 Aug 2014, 03:49

aamii wrote:在①中,我当前用的是”汉字拼音首字母“对应表,用查表的方法获取。有没有像tmplishi那样的”方法“获得”多音字“呢?
tmplishi 的方法也是查表,和你的方法没有本质差异。
aamii
Posts: 47
Joined: 23 May 2014, 03:50

Re: 如何判断一个字符串匹配另一个含中文字符串的一部分

16 Aug 2014, 08:13

感谢专门开帖讨论这个问题。
我的【汉字拼音对应表】是一个ini,当然:
a 啊阿呵吖锕(錒)嗄腌
xh 行

这样的这样的表一样可以完成任务,但是这样的话ini更直截了当。如果有码表方式解决更好,没有也将就。
amnesiac把问题更加深入了,期待能解决。

User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

Re: 如何判断一个字符串匹配另一个含中文字符串的一部分

16 Aug 2014, 20:20

@aamii,如果方便,请提供你所用方法的测试代码和相关文件(如 ini 文件)。

说实话,尽管都是查表,但要具体实现出来还是很有挑战的(思路倒是不难)。
aamii
Posts: 47
Joined: 23 May 2014, 03:50

Re: 如何判断一个字符串匹配另一个含中文字符串的一部分

17 Aug 2014, 01:52

我简化一个贴这里:

Code: Select all

; 第一部分:由中文字串生成到拼音首字
Str:="自行车"
loop,parse,Str
{
	IniRead,t,拼音表.ini,汉字拼音首字表,%a_loopfield%
	If(t="error")
		Str_PY .= "[" A_LoopField "]"
	Else
		Str_PY .= "[" t "]"
}
MsgBox %Str_PY%

; 第二部分,输入的字母,查匹配
InputBox,in
Loop,parse,in
{
	match .="\[[^\]]*" A_LoopField "[^\]]*\]"
}
MsgBox %match%
MsgBox % regexmatch( Str_PY, "i)" match "")

ini倒是简单:

Code: Select all

[汉字拼音首字表]
自=z
行=xh
车=jc
User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

Re: 如何判断一个字符串匹配另一个含中文字符串的一部分

17 Aug 2014, 05:04

嗯,这是其中一种思路,能判断出是否匹配。
不过若按开始提出的问题来看,仍存在两个问题:
  • 不支持全拼
  • 返回的位置不准确
或许你的问题无需考虑这两点?
User avatar
amnesiac
Posts: 186
Joined: 22 Nov 2013, 03:08
Location: Egret Island, China
Contact:

Re: 如何判断一个字符串匹配另一个含中文字符串的一部分

20 Aug 2014, 03:09

好吧,也许你没有兴趣,这样的话我贴完代码后也把问题修改为 [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 的方案,我考虑过,支持简拼也不错了,而且效率应该比刚才的代码更好。
aamii
Posts: 47
Joined: 23 May 2014, 03:50

Re: [SOLVED]如何判断一个字符串匹配另一个含中文字符串的一部分

21 Aug 2014, 02:19

:) amnesiac ,这两天没上来。
我的确只要实现了拼音首字即可,这样非常符合习惯,因为全拼的话,对于输入法常开的人而言,直接上中文即可。
其实用那正则匹配后,就几乎解决了我的需求。
你的代码我下载,学习下先。再次感谢。

Return to “请求帮助”

Who is online

Users browsing this forum: No registered users and 3 guests