智能文件名排序

默认排序问题

windows排序

Windows的资源管理中,提供了文件名的智能排序功能,可以识别出文件名中数字(数字位数不相同),然后比较数字大小进行排序,如下图:

代码默认排序

但在C#中的列表排序中则是按照从左到右一个一个字符进行比较进行排序,如下图:

List<string> list=new List<string>();
list.Add("文件(11)");
list.Add("文件(22)");
list.Add("文件(1)");
list.Add("文件(2)");
list.Add("文件(3)");
list.Add("文件(4)");
list.Sort();
list.ForEach(l=>Console.WriteLine(l));

运行效果

排序改进

文件名比较方法

        public static int FileNameCompare(string s1, string s2)
        {
            MatchCollection matchList1 = Regex.Matches(s1, @"\d+");//找出字符串s1中的数字
            MatchCollection matchList2 = Regex.Matches(s2, @"\d+");//找出字符串s2中的数字
            int minCount = matchList1.Count >= matchList2.Count ? matchList2.Count : matchList1.Count;
            for (int i = 0; i < minCount; i++)
            {//循环数字一一比较
                if (matchList1[i].Index != matchList2[i].Index)
                    break;//数字位置不同,直接使用字符串比较

                if (s1.Substring(0, matchList1[i].Index) != s2.Substring(0, matchList2[i].Index))
                    break;//数字之前字符不同,直接使用字符串比较

                if (matchList1[i].Value == matchList2[i].Value)
                    continue;//数字相同时,比较下一组数字

                int s = matchList1[i].Value.Length - matchList2[i].Value.Length;
                if (s == 0)
                    break;//数字位数相同,直接使用字符串比较

                string temp = "";
                if (s > 0) //这里不直接比较数字,是为了对数字之后的字符串再进行比较
                {
                    //当s1的数字长度大于s2时,对s2的前面进行补0操作,然后在比较s1与s2字符串
                    temp = s2;
                    for (int n = 0; n < s; n++)
                    {
                        temp = s2.Insert(matchList2[i].Index, "0");
                    }
                    int r = s1.CompareTo(temp);
                    return r == 0 ? -1 : r;
                }
                if (s < 0)
                {
                    //当s1的数字长度小于s2时,对s1的前面进行补0操作,然后在比较s1与s2字符串
                    temp = s1;
                    for (int n = 0; n < Math.Abs(s); n++)
                    {
                        temp = s1.Insert(matchList1[i].Index, "0");
                    }
                    int r = temp.CompareTo(s2);
                    return r == 0 ? 1 : r;
                }
            }
            return s1.CompareTo(s2);
        }

方法使用

            List<string> list = new List<string>();
            list.Add("文件(11)");
            list.Add("文件(22)");
            list.Add("文(11)件(1)");
            list.Add("文(2)件(2)");
            list.Add("文件(3)");
            list.Add("文件(4)");
            list.Sort((m1, m2) => Common.THMethod.FileNameCompare(m1, m2));
            list.ForEach(l => Console.WriteLine(l));

效果

 

猜你喜欢

转载自www.cnblogs.com/zlulu/p/6214758.html