How to Get the Positions of Strings Filtered by Multi-Split Without using (MyString.IndexOf(part, p))

Mansour_Dalir 1,976 Reputation points
2024-11-06T13:25:30.6+00:00

Regarding the previous question MyQuestions There was no expected result due to the duplicate string between the splits. I want to achieve a very correct result with these two functions. thank

'ResultPosition {"54-58","60-64") This output is correct

    Sub Loading()
        Dim MultiSplit As String() = {"C", "B", "A"}
        Dim MyString As String = "}666[]777([}666[]777(]00[A]1111{C}22(B)33333{C}4{C}5{C}666[A]777(B)8(B)99{C}999[A]101010}666[]777("
        'ResultPosition {"54-58","60-64") This output is correct
        Dim ResultPosition As String() = GetPositionsByMultiSplit(MyString, MultiSplit.ToList)
    End Sub

    Dim CurrentPosition As Integer = 0
    Dim LisPosition As New List(Of String)
    Function fWhere(inPart As String, idx As Integer, Finditem As String(), idxOfMultiSplit As Byte) As Boolean
        CurrentPosition += inPart.Length + Finditem(idxOfMultiSplit).Length
        If idxOfMultiSplit = Finditem.Count - 1 OrElse inPart.Contains(Finditem(idxOfMultiSplit + 1)) Then
            Return True
        Else
            Return False
        End If
    End Function
    Function GetPositionsByMultiSplit(BodyText As String, MultiSplit As List(Of String)) As String()
        Dim result = New List(Of String) From {BodyText}
        Dim p As Integer = 0  ' Start position for searching
        For i = 0 To MultiSplit.Count - 1
            Dim item = MultiSplit(i)
            result = result.
                SelectMany(Function(str) Split(str, item, Compare:=CompareMethod.Text)).
                Where(Function(part, idx) fWhere(part, idx, MultiSplit.ToArray, i)).
                ToList()
        Next
        Dim positions = result.
            Select(Function(part)
                       Dim startIndex = BodyText.IndexOf(part, p)
                       Dim endIndex = startIndex + part.Length - 1
                       p = endIndex + 1  ' Move start position to after the found part
                       Return $"{startIndex}-{endIndex}"
                   End Function).
            ToArray()
        Return positions
    End Function

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,743 questions
0 comments No comments
{count} votes

Accepted answer
  1. Jiachen Li-MSFT 32,451 Reputation points Microsoft Vendor
    2024-11-07T03:11:41.8333333+00:00

    Hi @Mansour_Dalir ,

    You can try creating a separate array of record positions, and record the position of the result after each split.

    Here is an example.

        Function MultiFinderStringPositions(BodyText As String, MultiFind As List(Of String)) As String()
            Dim result1 As String() = {BodyText}
            Dim result2 As String() = {}
            Dim result3 As String() = {}
            Dim startindex As Integer = 0
            Dim positions1 As Integer() = {}
            Dim positions2 As Integer() = {}
            For Each item In MultiFind
                Dim idx As Integer = MultiFind.IndexOf(item)
                If idx = MultiFind.Count - 1 Then
                    For i = 0 To result1.Length - 1
                        Dim res As String() = result1(i).Split(item)
                        result2 = result2.Concat(res).ToArray
                        For Each str As String In res
                            positions2 = positions2.Append(result1(i).IndexOf(str, startindex) + positions1(i)).ToArray
                            startindex = result1(i).IndexOf(str, startindex) + str.Length - 1
                        Next
                        startindex = 0
                    Next
                Else
                    For i = 0 To result1.Length - 1
                        Dim res As String() = result1(i).Split(item).Where(Function(f) f Like "*" & MultiFind(idx + 1) & "*").Select(Function(f) f).ToArray
                        result2 = result2.Concat(res).ToArray
                        For Each str As String In res
                            If idx = 0 Then
                                positions2 = positions2.Append(BodyText.IndexOf(str, startindex)).ToArray
                                startindex = BodyText.IndexOf(str, startindex) + str.Length - 1
                            Else
                                positions2 = positions2.Append(result1(i).IndexOf(str, startindex) + positions1(i)).ToArray
                                startindex = result1(i).IndexOf(str, startindex) + str.Length - 1
                            End If
                        Next
                        startindex = 0
                    Next
                    startindex = 0
                    result1 = result2
                    result2 = {}
                    positions1 = positions2
                    positions2 = {}
                End If
            Next
            For i = 0 To result2.Length - 1
                result3 = result3.Append((positions2(i) & "-" & (positions2(i)) + result2(i).Length - 1).ToString).ToArray
            Next
            Return result3
        End Function
    
    

    Best Regards.

    Jiachen Li


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.