对 MBCS 文本的 QuickSearch 搜索的误搜

来源:互联网 发布:淘宝如何添加公益宝贝 编辑:程序博客网 时间:2024/04/28 11:35
作者: JIURL
邮箱: thejiurl@gmail.com
主页: http://jiurl.blogsome.com/
http://jiurl.yeah.net/

[前言]

这篇文章是以前写给自己备忘的一个研究文档的节选。

[MBCS]

MBCS: Multi-Byte Character Set
DBCS: Double-Byte Character Set

MBCS 文本中,既可能有1个字节的 Ascii 字符,又可能有2个字节的 DBCS 字符。
硬盘上的大多数文本文件就是以 MBCS 方式来保存的。

[区分大小写的搜索]

QuickSearch 寻找匹配串,是以字节为单位来进行匹配的,
对字节的256个可能值,建立 MoveLenTable[] 表,来计算移动距离,
详细见 QuickSearch.txt 中的介绍。

对于 MBCS 文本来说,这样的匹配结果,可能有误搜,但是肯定没有漏搜。
我们应该去除掉误搜的情况。

会产生 DBCS TrailByte 引起的误搜。

DBCS TrailByte 引起的误搜,一种情况,比如:

szPattern 为 "gabc"
szText 为 "鎔abc xyz"

'鎔'是一个 DBCS 字符,编码为 0xe6 0x67。
'g' 是一个 ASCII 字符,编码为 0x67。

用 szPattern 对 szText 进行区分大小写的搜索,会得到一个匹配,
匹配串从 DBCS 字符 '鎔' 的 TrailByte 开始,
而实际上,并不应该有匹配,所以就出现了误搜。


DBCS TrailByte 引起的误搜,另一种情况,比如:

略。

[不区分大小写的搜索]

对于不区分大小写的搜索,

对于文本中的每个字节,不管它是一个 ascii 字符,还是一个 dbcs 字符的 LeadByte,TrailByte,都当作 ascii 字节来处理,只要它落在了 ascii 英文字母的范围内就进行不区分大小写处理。

由此,可能引起误搜,所以对匹配结果还需要进行误搜处理,去掉误搜的情况即可。

不区分大小写处理,包括:
建立 MoveLenTable[] 的时候,同一个英文字母,大写对应项,和,小写对应项,的值相同。

比较 chFirstPatternChar 的时候,应该既和 chFirstPatternChar 的大写值比较,又和 chFirstPatternChar 小写值比较。

进行串匹配的时候,也应该进行 不区分大小写 的串匹配。

详细实现参考 QuickSearchNotMatchCase() 函数的源码。

对于 MBCS 文本来说,这样的匹配结果,可能有误搜,但是肯定没有漏搜。
我们应该去除掉误搜的情况。

同样存在和 区分大小写的搜索 一样的,DBCS TrailByte 引起的误搜。
除此之外,还存在 不区分大小写 引起的误搜。

不区分大小写 引起的误搜,比如:

szPattern 为 "鎔abc"
szText 为 "鍳abc xyz"

'鎔'是一个 DBCS 字符,编码为 0xe6 0x67。
'鍳'是一个 DBCS 字符,编码为 0xe6 0x47。

DBCS 的 TrailByte 本身是一个字符的一部分,不存在大小写问题,但是,
匹配是以字节来进行的,并不知道这个字节是否是一个 DBCS 的 TrailByte,只要看到了这个字节的值落在了英文字母的范围内,就进行不区分大小写的处理,导致了认为 0x67 和 0x47 是匹配的。

用 szPattern 对 szText 进行区分大小写的搜索,会得到一个匹配,
匹配串为"鍳abc",
而实际上,并不应该有匹配,所以就出现了误搜。

可以看到,只有 szPattern 中含有 DBCS 字符,才可能出现这种误搜。

[误搜的去除]

略。

[误搜的出现几率]

误搜的出现几率是非常小的,这是因为:

不管是两种误搜中的哪种,都是由于 DBCS 字符的 TrailByte 小于 0x80,落在了 ascii 字符的范围内,而本身 DBCS 的 TrailByte 小于 0x80 的字符,都是些不太常用的汉字。

出现 DBCS 字符 TrailByte 小于 0x80 的几率较小,
又碰巧出现 szPattern 和 szText 的误搜的几率就更小了。 
原创粉丝点击