首页 > 解决方案 > 对字符串数组进行排序

问题描述

我输入了以下格式的字符串

"[1_5,3,7,1],[1_2,4,1,9],[],[1_1,,4,,,9,2]"

我需要获得的是相同的字符串,但_排序后的数字:

"[1_1,3,5,7],[1_1,2,4,9],[],[1_1,2,4,9,,,]"
Dim tmprequestedArea_selectionAreaIn As String = "[1_5,3,7,1],[1_2,4,1,9],[],[1_1,,4,,,9,2]"

tmprequestedArea_selectionAreaIn = Regex.Replace(requestedArea_selectionAreaIn,"\],\[","#")
tmprequestedArea_selectionAreaIn = Regex.Replace(tmprequestedArea_selectionAreaIn,"\[|\]","")

bracList.AddRange(tmprequestedArea_selectionAreaIn.Split(New Char() {"#"c}, StringSplitOptions.None ))

If sortNumber Then 
    'Split braclist by _ and puts the value in strList 
    'If after _ is only one number put only that number, else split it by char "," and put in strList the join of the split by , array
    'Sort the array
    'in previous example strList will contain a,b,c in position 0 and _d_f (instead of f,d) in position 1
    For i As Integer = 0 To bracList.Count -1
        Dim tmp As String()
        Dim tmpInt As New System.Collections.Generic.List(Of Integer) 
        If Not(String.IsNullOrEmpty(bracList(i))) Then 
            Dim tmpRequested As String = bracList(i).Split(New Char() {"_"c})(0)
            Dim tmpSelection As String = bracList(i).Split(New Char() {"_"c})(1)

        If tmpSelection.Contains(",") Then
            tmp = tmpSelection.Split(New Char() {","c})
            For j As Integer = 0 To tmp.Length -1
                tmpInt.Add(Convert.toInt32(tmp(j)))
            Next
            tmpInt.Sort
            strList.Add("["  + tmpRequested + "_" + String.Join(",",tmpInt ) + "]")
        Else
            strList.Add("[" +  tmpRequested + "_" + tmpSelection + "]" )
        End If
        Else
            strList.Add("[]")
        End If
    Next i

我正在寻找一种更好的方法来管理它。

标签: regexvb.netlinq

解决方案


试试这个,作为你现在正在做的可能的替代品。

给定这个输入字符串:

Dim input As String = "[1_5,3,7,1],[1_2,4,1,9],[],[1_1,,4,,,9,2]"

注意:这也将处理十进制值而无需更改。例如,

"[1_5.5,3.5,7,1],[1_2.564,4,2.563,9],[],[1_1,,4.23,,,9.0,2.45]"

您可以使用此模式提取括号的内容:\[(.*?)\]并使用Regex.Matches返回匹配该模式的所有子字符串的MatchCollection 。

然后使用StringBuilder作为容器在处理部件时重建字符串。

Imports System.Linq
Imports System.Text.RegularExpressions

Dim pattern As String = "\[(.*?)\]"
Dim matches = Regex.Matches(input, pattern, RegexOptions.Singleline)
Dim sb As New StringBuilder()

For Each match As Match In matches
    Dim value As String = match.Groups(1).Value
    If String.IsNullOrEmpty(value) Then
        sb.Append("[],")
        Continue For
    End If
    Dim sepPosition As Integer = value.IndexOf("_"c) + 1
    sb.Append("[" & value.Substring(0, sepPosition))
    Dim values = value.Substring(sepPosition).Split(","c)
    sb.Append(String.Join(",", values.Where(Function(n) n.Length > 0).OrderBy(Function(n) CDec(n))))
    sb.Append(","c, values.Count(Function(n) n.Length = 0))
    sb.Append("],")
Next

Dim result As String = sb.ToString().TrimEnd(","c)

如果您不了解 LINQ,这就是它正在做的事情:

String.Join(",", values.Where(Function(n) n.Length > 0).OrderBy(Function(n) CDec(n)))

values是一个字符串数组,由 生成String.Split()

values.Where(Function(n) n.Length > 0)Enumerable(Of String):从values Where内容创建一个n, 是一个长度为 的字符串> 0
我本来可以写values.Where(Function(n) Not String.IsNUllOrEmpty(n))的。

.OrderBy(Function(n) CDec(n))):Enumerable(Of String)使用转换为 Decimal 的字符串值对结果进行排序,并生成一个Enumerable(Of String),将其传递回String.Join(),以重建字符串,","c在各部分之间添加一个 char ( )。

values.Count(Function(n) n.Length = 0):计算values具有Length = 0(空字符串)的元素。这是用逗号表示的空元素的数量,附加在部分字符串的末尾。


推荐阅读