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

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

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: 546
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 ,这两天没上来。
我的确只要实现了拼音首字即可,这样非常符合习惯,因为全拼的话,对于输入法常开的人而言,直接上中文即可。
其实用那正则匹配后,就几乎解决了我的需求。
你的代码我下载,学习下先。再次感谢。
list
Posts: 222
Joined: 26 Mar 2014, 14:03
Contact:

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

19 Aug 2023, 08:43

Apologies for posting in English, I found this thread while searching the forum for PinYin.

Background: Lintalist can search for text using incremental search - https://lintalist.github.io/#Searching -

Typing 'sea tex' will find 'searching text' but ALSO 'searching for text' or 'text about the sea'

Someone asked if PinYin search could be added to Lintalist, so as far as I understand it you would type "w" or "wo" and be able to find "我".

As I know nothing about it is is a bit of a stab in the dark.

Part 1 - AutoHotkey only solution (no DLL)

But this is what I've come up with so far and perhaps you could have a look to see if it is actually worth adding and useful:

https://github.com/lintalist/lintalist/issues/253#issuecomment-1684944005
(code + data table used)

I've converted the hex values in the http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/CJK.html Uni2Pinyin table to Decimal values so SetFormat Hex/Dec Conversion + SubStr are no longer needed and can use Ord() directly.

Is this actually useful for my use case?

Part 2: - TCMATCH DLL

A few posts above in the GH issue there is also a TCMATCH DLL version, is that actually better or faster?
For it to work you need tcmatch64.dll (tcmatch.dll) which is part of a Total Commander tool"
https://ghisler.ch/board/viewtopic.php?t=22592
You can download the DLLs here https://1drv.ms/f/s!AC5p-6IfkMT4g%51%51
In order for the download to work you may need to select multiple files as downloading one file doesn't (always) seem to work, select, select:

QuickSearch eXtended.zip (has the DLLs)
QuickSearch eXtended - source.zip
tcmatch.pdf

then press download.

You need to copy
tcmatch.dll
tcmatch64.dll
tcmatch.tbl
and create the tcmatch.ini as posted above

Return to “请求帮助”

Who is online

Users browsing this forum: No registered users and 23 guests