[WPF] 脱机环境实现支持拼音含糊搜刮的AutoCompleteBox

打印 上一主题 下一主题

主题 950|帖子 950|积分 2850

AutoCompleteBox是一个常见的提高输入服从的组件,很多WPF的第三方控件库都提供了这个组件,但根本都是字符串的子串匹配,不支持拼音含糊匹配,例如无法通过输入ldh或liudehua匹配到刘德华。要实现拼音含糊搜刮功能,通常会采用分词、数据库等技术对待匹配数据集进行预处理惩罚。某些场景受制于条件限制,无法对数据进行预处理惩罚,本文将介绍在这种情况下如何实现支持拼音含糊搜刮的AutoCompleteBox,先来看下实现效果。

主要思绪

WPF中并没有AutoCompleteBox控件,我们可以使用TextBox输入搜刮内容,用Popup+ListBox表现匹配到的提示内容。拼音含糊匹配汉字则采用字符串匹配的方式来解决,也就是搜刮字符串和待匹配数据集的内容全部转换为拼音字符串,然后进行子串匹配。这里有三个问题必要解决。

  • 汉字转换为拼音。
  • 拼音如何匹配。 例如ldh、lidh、ldhua、liudehua、dhua、hua等都能匹配到刘德华
  • 匹配后的内容高亮表现。 当输入dhua匹配到刘德华时必要把德华两个字高亮。
汉字转换拼音

微软为了开发者实现国际化语言的互转,提供了Microsoft Visual Studio International Pack,这个扩展包内里有中文、日文、韩文、英语等各国语言包,并提供方法实现互转、获取拼音、获取字数、甚至获取笔画数等等。下载Microsoft Visual Studio International Pack 1.0 SR1安装后,在安装目次中找到ChnCharInfo.dll,然后在项目中添加引用。
ChnCharInfo.dll获取汉字的拼音时只能传入单个字符,因此只能把汉字字符串拆分成一个个字符处理惩罚,由于汉字存在多音字情况以及缺少语义信息,获取的拼音组合可能是多个,例如输入长江,返回的是changjiang和zhangjiang。汉字转拼音的方法如下:
  1. /// <summary>
  2. /// 获取汉字拼音
  3. /// </summary>
  4. /// <param name="str">待处理包含汉字的字符串</param>
  5. /// <param name="split">拼音分隔符</param>
  6. /// <returns></returns>
  7. public static List<string> GetChinesePhoneticize(string str, string split = "")
  8. {
  9.     List<string> result = new List<string>();
  10.     char[] chs = str.ToCharArray();
  11.     Dictionary<int, List<string>> totalPhoneticizes = new Dictionary<int, List<string>>();
  12.     for (int i = 0; i < chs.Length; i++)
  13.     {
  14.         var phoneticizes = new List<string>();
  15.         if (ChineseChar.IsValidChar(chs[i]))
  16.         {
  17.             ChineseChar cc = new ChineseChar(chs[i]);
  18.             phoneticizes.AddRange(cc.Pinyins.Where(r => !string.IsNullOrWhiteSpace(r)).ToList<string>().ConvertAll(p => Regex.Replace(p, @"\d", "").ToLower()).Distinct());
  19.         }
  20.         else
  21.         {
  22.             phoneticizes.Add(chs[i].ToString());
  23.         }
  24.         if (phoneticizes.Any())
  25.             totalPhoneticizes[i] = phoneticizes;
  26.     }
  27.     foreach (var phoneticizes in totalPhoneticizes)
  28.     {
  29.         var items = phoneticizes.Value;
  30.         if (result.Count <= 0)
  31.         {
  32.             result = items;
  33.         }
  34.         else
  35.         {
  36.             var newtotalPhoneticizes = new List<string>();
  37.             foreach (var totalPingYin in result)
  38.             {
  39.                 newtotalPhoneticizes.AddRange(items.Select(item => totalPingYin + split + item));
  40.             }
  41.             newtotalPhoneticizes = newtotalPhoneticizes.Distinct().ToList();
  42.             result = newtotalPhoneticizes;
  43.         }
  44.     }
  45.     return result;
  46. }
复制代码
拼音匹配算法

汉字转换后的拼音字符串有多组,只要搜刮字符串转换的拼音组合有一组与待匹配字符串转换的拼音组合中匹配,则认为匹配成功,为了后续高亮表现,必要记录下匹配的起始位置以及匹配的子串长度。代码如下:
  1. public static bool fuzzyMatchChar(string character, string input, out int matchStart, out int matchCount)
  2. {
  3.     List<string> regexs = GetChinesePhoneticize(input);
  4.     List<string> targetStr = GetChinesePhoneticize(character, " ");
  5.     matchStart = -1;
  6.     matchCount = 0;
  7.     foreach (string regex in regexs)
  8.     {
  9.         foreach (string target in targetStr)
  10.         {
  11.             if (PhoneticizeMatch(regex, target.Split(' '), out matchStart, out matchCount))
  12.                 return true;
  13.         }
  14.     }
  15.     return false;
  16. }
复制代码
这里的PhoneticizeMatch方法是拼音匹配算法的核心,是在【算法】拼音匹配算法这篇博文中算法的底子上稍作修改,详细的思绪及图解可阅读这篇博文。
高亮匹配的子串

WPF中可以通过TextEffect的PositionStart、PositionCount以及Foreground属性设置字符串中必要高亮内容的起始位置、长度以及高亮颜色。前面拼音匹配算法中获取了匹配成功子串的起始位置和长度,也正是为此做预备。之前在WPF使用TextBlock实现查找结果高亮表现一文中有详细介绍思绪和代码,此处不再赘述。
小结

本文介绍了在不依赖数据库及分词的情况下如何实现拼音含糊搜刮并在目标字符串中高亮表现,方法中也存在诸多不足必要完善的地方。

  • 匹配计谋存在误匹配。例如输入石,可以匹配出拼音为shi的所有汉字。
  • 匹配算法服从不敷高。测试过程中,待匹配数据会合模拟了500条数据,匹配耗时大概在400~500ms左右。
代码示例

ChinesePhoneticizeFuzzyMatch

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

勿忘初心做自己

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表