1

I have as input the string in the below format

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

What I need to obtain is the same string but with the number after the _ sorted:

"[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

I'm looking for a better way to manage it.

0

1 Answer 1

3

Try this, as a possible substitute for what you're doing now.

Given this input string:

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

Note: this will also deal with decimal values without changes. E.g.,

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

You can extract the content of the brackets with this pattern: \[(.*?)\] and use Regex.Matches to return a MatchCollection of all the substrings that match the pattern.

Then use a StringBuilder as a container to rebuild the string while the parts are being treated.

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)

If you don't know about LINQ, this is what it's doing:

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

values is an array of strings, generated by String.Split().

values.Where(Function(n) n.Length > 0): creates an Enumerable(Of String) from values Where the content, n, is a string of length > 0.
I could have written values.Where(Function(n) Not String.IsNUllOrEmpty(n)).

.OrderBy(Function(n) CDec(n))): Orders the resulting Enumerable(Of String) using the string value converted to Decimal and generates an Enumerable(Of String), which is passed back to String.Join(), to rebuild the string, adding a char (","c) between the parts.

values.Count(Function(n) n.Length = 0): Counts the elements of values that have Length = 0 (empty strings). This is the number of empty elements that are represented by a comma, appended at the end of the partial string.

Sign up to request clarification or add additional context in comments.

2 Comments

I tried but i take the error Public member 'Where' on type 'String()' not found and i fix replacing [Where]
It's LINQ. You have to add Imports System.Linq on top of your class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.