将串分成可能的组合AA-200A / B / C或AA-100到105的范围

时间:2018-06-05 10:22:58

标签: string vb.net split

我在没有正确输入的文本文件中(完整地)有字符串(它们实际上是部件号)。我需要拆分然后将它们连接起来以表示完整的部件号。

例如: 字符串 ZVN-798-100A / B / C 应输入为:

  • ZVN-798-100A
  • ZVN-798-100B
  • ZVN-798-100C

字符串 XPD-279-100到103 应该输入为:

  • XPD-279-100
  • XPD-279-101
  • XPD-279-102
  • XPD-279-103

我的代码正确分割了这些:

  • AA-10-100A / B / C
  • BB-20-100A至C
  • DD-40-100 / 110/120
  • EE-50-100A - H

但不是这些:

  • CC-30-100至105
  • FF-60-110至15

为了简单地发布到SO,我创建了一个代码的单个子代码:

Private Sub btnRun_Click(sender As System.Object, e As System.EventArgs) Handles btnRun.Click

    Dim arrSplitEach(2) As String
    arrSplitEach(0) = "\"
    arrSplitEach(1) = "/"
    arrSplitEach(2) = ","

    Dim arrSplitAll(2) As String
    arrSplitAll(0) = " to "
    arrSplitAll(1) = " thru "
    arrSplitAll(2) = "~"

    Dim strFromFile(5) As String
    strFromFile(0) = "AA-10-100A/B/C"
    strFromFile(1) = "BB-20-100A to C"
    strFromFile(2) = "CC-30-100 thru 15"
    strFromFile(3) = "DD-40-100 / 110 / 120"
    strFromFile(4) = "EE-50-100A~H"
    strFromFile(5) = "FF-60-100 to 115"

    Dim arrOutput As New ArrayList

    Dim iSplitEach As Integer
    Dim iSplitAll As Integer

    Dim strSplitter As String

    rtbOutput.Clear()
    rtbOutput.Update()

    For iString As Integer = LBound(strFromFile) To UBound(strFromFile)

        Dim s As String = strFromFile(iString).ToString.Trim

        If s <> "" Then

            For iSplitEach = LBound(arrSplitEach) To UBound(arrSplitEach)
                strSplitter = arrSplitEach(iSplitEach).ToString

                If s.Contains(strSplitter) Then
                    Dim parts As Array = Replace(s, " ", "").Split(strSplitter)
                    Dim derived As New List(Of String)

                    derived.Add(parts(0))

                    Dim intLoopParts As Integer
                    For intLoopParts = 1 To parts.Length - 1
                        If Not Len(parts(intLoopParts)) = 0 And Not parts(0).Length < Len(parts(intLoopParts)) Then
                            derived.Add(parts(0).Remove(parts(0).Length - Len(parts(intLoopParts))) & parts(intLoopParts))
                        End If
                    Next

                    For Each strPart As String In derived
                        'If strNotVerifiedSplit.Contains(strPart.ToLower.Trim) = False Then
                        If Not arrOutput.Contains(strPart.Trim) Then
                            arrOutput.Add(Replace(strPart.Trim, " ", ""))
                            strFromFile(iString).Equals(strFromFile(iString) & " | Split")
                        End If
                    Next

                    derived.Clear()

                End If
            Next iSplitEach

        For iSplitAll = LBound(arrSplitAll) To UBound(arrSplitAll)
            strSplitter = arrSplitAll(iSplitAll).ToString

            If s.Contains(strSplitter) Then

                Dim strMain As String = Replace(Strings.Left(s, InStr(s, strSplitter) - 1), " ", "")

                Dim strStart As String = Mid(s, InStr(s, strSplitter) - 1, 1)
                Dim strEnd As String = Strings.Right(s, 1)

                Dim strToPlace As String

                For Each c As Char In "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
                    strToPlace = Strings.Left(strMain, Len(strMain) - 1) & c

                    If Not strToPlace = "" Then

                        If Not arrOutput.Contains(strToPlace.Trim) Then
                            arrOutput.Add(Replace(strToPlace, " ", ""))
                            strFromFile(iString).Equals(strFromFile(iString) & " | Split")
                        End If

                    End If

                    If c = strEnd Then
                        Exit For
                    End If
                Next c

            End If
        Next iSplitAll
        End If
        s = ""
    Next iString

    For iOutput As Integer = 0 To arrOutput.Count - 1
        rtbOutput.SelectionStart = rtbOutput.TextLength
        rtbOutput.SelectionLength = 0

        If Not arrOutput(iOutput) = "" Then
            rtbOutput.AppendText(arrOutput(iOutput).Trim & vbCrLf)
        End If
    Next

End Sub

我发现很多关于拆分字符串的文章,但是没有看到这个特定情况的重复。

为了处理数字范围而必须添加另一块代码似乎有些过分,我希望有人可以提供一些明智的建议来改进我现有的代码。

1 个答案:

答案 0 :(得分:1)

我会这样做并避免VB6代码风格:

Private fList() As String = {"\", "/", ","}
Private fRange() As String = {" to ", " thru ", "~"}
Private Const Letters As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

Private Function SplitParts(Part As String) As IEnumerable(Of String)
    Dim S, Vals() As String
    For Each S In fList
        Vals = Split(Part, S)
        If Vals.Length > 1 Then Return FixList(Vals)
    Next
    For Each S In fRange
        Vals = Split(Part, S)
        If Vals.Length > 1 Then Return FixRange(Vals)
    Next
    Return {Part}
End Function

Private Function FixList(Vals() As String) As List(Of String)
    Dim Ret As New List(Of String), First, Suffix As String
    First = Vals.First.Trim
    Ret.Add(First)
    For i As Integer = 1 To Vals.Length - 1
        Suffix = Vals(i).Trim
        Ret.Add(First.Substring(0, First.Length - Suffix.Length) & Suffix)
    Next
    Return Ret
End Function

Private Function FixRange(Vals() As String) As IEnumerable(Of String)
    Dim Range As New List(Of String), First, Last, Format As String, i, iMin, iMax As Integer
    First = Vals.First.Trim : Last = Vals.Last.Trim
    If Integer.TryParse(Last, iMax) AndAlso Integer.TryParse(First.Substring(First.Length - Last.Length), iMin) Then
        Format = New String("0"c, Last.Length)
        For i = iMin To iMax
            Range.Add(i.ToString(Format))
        Next
    ElseIf Last.Length = 1 Then
        iMin = Letters.IndexOf(First.Last) : iMax = Letters.IndexOf(Last)
        If iMin >= 0 AndAlso iMax >= 0 Then
            For i = iMin To iMax
                Range.Add(Letters(i))
            Next
        End If
    End If
    First = First.Substring(0, First.Length - Vals.Last.Trim.Length)    'Prefix
    Return Range.Select(Function(X) First & X)
End Function