【问题标题】:sorting strings containing numbers and letters对包含数字和字母的字符串进行排序
【发布时间】:2016-10-28 22:41:50
【问题描述】:

我需要对一个场景编号列表进行排序,该列表实际上是一个字符串列表,包含数字和字母。

这是列表

101-11
102-1
101-10
101-8
103-10
101-8A
101-9
103-4
103-4B

我已经关注了一个比较器

public class SceneComparer : IComparer
{
    private readonly Regex sceneRegEx = new Regex(@"(\D*)(\w*)", RegexOptions.Compiled);

    public int Compare(object x, object y)
    {
        Scene sceneX = x as Scene;
        Scene sceneY = y as Scene;

        var firstSceneMatch = this.sceneRegEx.Match(sceneX.SceneNumber);

        var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value);
        var firstSceneAlpha = firstSceneMatch.Groups[2].Value;

        var secondSceneMatch = this.sceneRegEx.Match(sceneY.SceneNumber);

        var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value);
        var secondSceneAlpha = secondSceneMatch.Groups[2].Value;

        if (firstSceneNumeric < secondSceneNumeric)
        {
            return -1;
        }

        if (firstSceneNumeric > secondSceneNumeric)
        {
            return 1;
        }

        return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);            
    }
}

这给了我以下结果

101-8
101-8A
101-9
102-1
103-4
103-4B
101-10
101-11
103-10

看起来它只是对破折号之前的第一个数字和字母数字进行排序,但它不会对破折号之后的数字进行排序以获得以下所需的结果。

101-8
101-8A
101-9
101-10
101-11
102-1    
103-4
103-4B
103-10

关于如何获得所需结果的任何想法。

【问题讨论】:

  • 使用“-”将字符串分割成一个元组然后使用LINQ按Item1然后Item2排序。

标签: c# regex sorting


【解决方案1】:

您必须 Split 字符串并提取其中的数字以请求对这些字段进行排序。

// Assuming you have this...
List<string> list = new List<string>()
{
    "101-11",
    "102-1",
    "101-10",
    "101-8",
    "103-10",
    "101-8A",
    "101-9",
    "103-4",
    "103-4B"
};


// You could do this.
var result = list.Select(x=>
    {
        var splits = x.Split('-');
        return new 
        {
            first = int.Parse(splits[0]),
            second = int.Parse(Regex.Match(splits[1], @"\d+").Value),
            item =x

        };
    })
    .OrderBy(x=>x.first)
    .ThenBy(x=>x.second)
    .Select(x=>x.item)
    .ToList(); 

查看Demo

【讨论】:

    【解决方案2】:

    你很亲密。使用Matches 而不是Match

    另外,请更正您的正则表达式,因为 \D 捕获非数字字符。

    public class SceneComparer : IComparer
    {
        private readonly Regex sceneRegEx = new Regex(@"(\d+)(\w+)?", RegexOptions.Compiled);
    
        public int Compare(object x, object y)
        {
            Scene sceneX = x as Scene;
            Scene sceneY = y as Scene;
    
            var firstSceneMatches = this.sceneRegEx.Matches(sceneX.SceneNumber);
            var secondSceneMatches = this.sceneRegEx.Matches(sceneY.SceneNumber);
    
            var matchesCount = Math.Min(firstSceneMatches.Count, secondSceneMatches.Count);
            for (var i = 0; i < matchesCount; i++)
            {
                var firstSceneMatch = firstSceneMatches[i];
                var secondSceneMatch = secondSceneMatches[i];
    
                var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value);
                var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value);
                if (firstSceneNumeric != secondSceneNumeric)
                {
                    return firstSceneNumeric - secondSceneNumeric;
                }
    
                var firstSceneAlpha = firstSceneMatch.Groups[2].Value;
                var secondSceneAlpha = secondSceneMatch.Groups[2].Value;
                if (firstSceneAlpha != secondSceneAlpha)
                {
                    return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
                }
            }
    
            return firstSceneMatches.Count - secondSceneMatches.Count;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-22
      • 2019-03-28
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 2021-08-12
      • 2012-08-07
      • 2019-05-26
      相关资源
      最近更新 更多