I am trying to create what I expect from the subroutine (GetAllPosition).
I don't know where to use RsultOfPostionAndLength
in the code to get the expected output
My expectation of the output for (RsultOfPostionAndLength
):
MultiSplit' For {"C", "B", "A"}
is: 55-5 '}666[' 61-5']777(' 67-3')8[' 71-6']hhhy('
MultiSplit' For {"A", "B", "C"}
is: 27-6 ']1111{' 34-4'}22(' 39-7')33333{' 47-3'}4{' 51-3 '}5{' 55-5'}666[' 78-4')99{' 83-5'}999['
Dim RsultOfPostionAndLength As List(Of String) 'Pattern is Position of String And Length Of Find
' 'MultiSplit' For {"C", "B", "A"} is: 55-5 '}666[' 61-5']777(' 67-3')8[' 71-6']hhhy('
' 'MultiSplit' For {"A", "B", "C"} is: 27-6 ']1111{' 34-4'}22(' 39-7')33333{' 47-3'}4{' 51-3 '}5{' 55-5'}666[' 78-4')99{' 83-5'}999['
Sub Setup()
Dim inString As String = "}666[]777([}666[]777(]00[A]1111{C}22(B)33333{C}4{C}5{C}666[A]777(B)8[A]hhhy(B)99{C}999[A]101010}666[]777("
Dim MultiSplit As String() = {"C", "B", "A"}
GetAllPosition(1, inString.Length, inString, MultiSplit, 0)
End Sub
Sub GetAllPosition(LastIdx As Integer, LastLen As Integer, inString As String, MultiSplit As String(), Level As Integer)
Dim spl As String() = Split(inString, ",")
Dim body As String = Mid(inString, LastIdx, LastLen)
'Dim LastIdx As Integer = spl(0)
Dim results As New List(Of String)
Dim Find As String = MultiSplit(Level)
Dim last As Integer = LastIdx
Dim index As Integer = -1
Do Until body.Length <= index
index = body.IndexOf(Find, index + 1)
If index = -1 AndAlso body.Length > last Then
index = body.Length
End If
Dim lenTexxt As Integer = Math.Abs(last - index) + 1
Dim part1 As String = Mid(body, last, lenTexxt)
Dim part As String = Mid(inString, last, lenTexxt)
Dim b As Boolean = MultiSplit.Skip(Level + 1).All(Function(c) part.IndexOf(c, comparisonType:=StringComparison.OrdinalIgnoreCase) > -1)
If b Then
results.Add(last & "," & lenTexxt & "," & part)
End If
last = index + 2
Loop
Level += 1
For Each g In results
Dim spl2 As String() = Split(g, ",")
GetAllPosition(spl2(0), spl2(1), inString, MultiSplit, Level)
Next
End Sub
You are trying a recursive approach, which is a good thing to do in this situation. My solution uses a Structure to store the results.
Structure ResultItem
Public Value As String
Public Position As Integer
Public Length As Integer
Public Overrides Function ToString() As String
Return $"{Position}-{Length} ""{Value}"""
End Function
End Structure
We have to split by the separator corresponding to the current level ("A", "B" or "C"). The last level must be treated differently to end the recursion and also because we do not have to test whether the next level separator is contained.
Sub Test()
Dim inString As String = "}666[]777([}666[]777(]00[A]1111{C}22(B)33333{C}4{C}5{C}666[A]777(B)8[A]hhhy(B)99{C}999[A]101010}666[]777("
Dim MultiSplit As String() = {"A", "B", "C"}
Dim result As List(Of ResultItem) = AllPositions(inString, 0, MultiSplit, 0)
For Each r As ResultItem In result
Console.WriteLine(r)
Next
End Sub
Public Function AllPositions(input As String, index As Integer, separators As String(), level As Integer) As List(Of ResultItem)
Dim separator As String = separators(level)
Dim parts As String() =
Split(input, separator, Compare:=CompareMethod.Text) 'Ignores case
Dim result = New List(Of ResultItem)()
If level = separators.Length - 1 Then
For Each part As String In parts
Dim item = New ResultItem With {
.Value = part,
.Position = index,
.Length = part.Length
}
result.Add(item)
index += part.Length + separator.Length
Next
Else
Dim nextSeparator As String = separators(level + 1)
For Each part As String In parts
If part.Contains(nextSeparator, StringComparison.OrdinalIgnoreCase) Then
result.AddRange(AllPositions(part, index, separators, level + 1))
End If
index += part.Length + separator.Length
Next
End If
Return result
End Function
Output of my console test:
26-6 "]1111{"
33-4 "}22("
38-7 ")33333{"
46-3 "}4{"
50-3 "}5{"
54-5 "}666["
77-4 ")99{"
82-5 "}999["