簡體   English   中英

排序包含數字和字母的字符串

[英]sorting strings containing numbers and letters

我需要對場景編號列表進行排序,實際上是一個字符串列表,其中包含數字和字母。

這是清單

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

關於如何獲得理想結果的任何想法。

您必須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

你很親密 使用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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM