一、使用PinYinConverterCore获取汉语拼音#

最新在做一个搜索组件,需要使用汉语拼音的首字母查询出符合条件的物品名称,由于汉字存在多音字,所以自己写查询组件不太现实,因此,我们使用微软提供的CHSPinYinConvCHSPinYinConv在.net core下载安装没有问题,但在.net framework会由于兼容性会安装失败,因此使用了PinYinConverterCore来实现汉字转拼音,PinYinConverterCore应该也是基于CHSPinYinConv开发的兼容包,后续的代码两个安装包环境下都可以使用。使用Nuget搜索PinYinConverterCore下载并安装,具体如下:

二、编写工具扩展类实现获取汉字的拼音#

由于汉字存在多音字,因此,通过汉字获取到的拼音是一个数组,具体如下:

  /// <summary>    /// 汉字转换拼音    /// </summary>    public static class PingYinUtil    {        private static Dictionary<int, List<string>> GetTotalPingYinDictionary(string text)        {            var chs = text.ToCharArray();             //记录每个汉字的全拼            Dictionary<int, List<string>> totalPingYinList = new Dictionary<int, List<string>>();             for (int i = 0; i < chs.Length; i++)            {                var pinyinList = new List<string>();                 //是否是有效的汉字                if (ChineseChar.IsValidChar(chs[i]))                {                    ChineseChar cc = new ChineseChar(chs[i]);                    pinyinList = cc.Pinyins.Where(p => !string.IsNullOrWhiteSpace(p)).ToList();                }                else                {                    pinyinList.Add(chs[i].ToString());                }                 //去除声调,转小写                pinyinList = pinyinList.ConvertAll(p => Regex.Replace(p, @"\d", "").ToLower());                 //去重                pinyinList = pinyinList.Where(p => !string.IsNullOrWhiteSpace(p)).Distinct().ToList();                if (pinyinList.Any())                {                    totalPingYinList[i] = pinyinList;                }            }             return totalPingYinList;        }        /// <summary>        /// 获取汉语拼音全拼        /// </summary>        /// <param name="text">The string.</param>        /// <returns></returns>        public static List<string> GetTotalPingYin(this string text)        {            var result = new List<string>();            foreach (var pys in GetTotalPingYinDictionary(text))            {                var items = pys.Value;                if (result.Count <= 0)                {                    result = items;                }                else                {                    //全拼循环匹配                    var newTotalPingYinList = new List<string>();                    foreach (var totalPingYin in result)                    {                        newTotalPingYinList.AddRange(items.Select(item => totalPingYin + item));                    }                    newTotalPingYinList = newTotalPingYinList.Distinct().ToList();                    result = newTotalPingYinList;                }            }            return result;        }         /// <summary>        /// 获取汉语拼音首字母        /// </summary>        /// <param name="text"></param>        /// <returns></returns>        public static List<string> GetFirstPingYin(this string text)        {            var result = new List<string>();            foreach (var pys in GetTotalPingYinDictionary(text))            {                var items = pys.Value;                if (result.Count <= 0)                {                    result = items.ConvertAll(p => p.Substring(0, 1)).Distinct().ToList();                }                else                {                    //首字母循环匹配                    var newFirstPingYinList = new List<string>();                    foreach (var firstPingYin in result)                    {                        newFirstPingYinList.AddRange(items.Select(item => firstPingYin + item.Substring(0, 1)));                    }                    newFirstPingYinList = newFirstPingYinList.Distinct().ToList();                    result = newFirstPingYinList;                }            }            return result;        }    }

三、编写测试用例#

我们编写一个测试用例,通过输入的汉字获取到汉语拼音的全拼和首字母缩写,具体如下:

               // 汉字输入                string text = TextBoxInput.Text;                 // 获取到汉语拼音的全拼                TextBoxTotal.Text = string.Join(",", text.GetTotalPingYin());                 // 获取到汉语拼音的首字母                TextBoxFirst.Text = string.Join(",", text.GetFirstPingYin());

我们编写录入一组用户名,然后根据输入输入的用户名的缩写,筛选出符合条件的人,我们可以使用Linq模糊查询,具体如下:

 public class Student    {        public string Name { get; set; }        public List<string> Pinyin { get; set; }    }
  StudentList = new List<Student>            {                new Student() {Name = "张三"},                new Student() {Name = "章黎"},                new Student() {Name = "张三丰"},                new Student() {Name = "李四"},                new Student() {Name = "王五"},                new Student() {Name = "John"},                new Student() {Name = "W.吴"},                new Student() {Name = "阿姨"},                new Student() {Name = "阿胶"},                new Student() {Name = "麦合苏提.麦合苏提"}            };
 var text = TextBoxSearch.Text;            foreach (var student in StudentList)            {                student.Pinyin = student.Name.GetFirstPingYin();            }             StudentList = StudentList.Where(s => s.Pinyin.Exists(p=>p.Contains(text))).ToList();