【问题标题】:How to split a string with multiple delimiters in vba excel?如何在vba excel中拆分具有多个分隔符的字符串?
【发布时间】:2011-10-06 21:09:58
【问题描述】:

我想使用 Excel VBA 拆分具有多个分隔符的字符串。其中一个字符串是:

d1-d2 d3 d4  

我们有一个破折号和一个空格作为两个分隔符。我尝试了split 函数,但它只使用一个分隔符。

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    您可以先对字符串执行Replace,然后再进行拆分:

    newString = Replace(origString, "-", " ")
    newArray = Split(newString, " ")
    

    【讨论】:

      【解决方案2】:

      用几个不同的分隔符分割;列出数组中的分隔符,用 for 循环替换它们,然后拆分:

      ' New delimiter
      tDelimNew = "myDelimiter"
      
      ' Replace each possible delimiter
      For Each tDelimOld In Array(";", " ", ".", "<==", ":", vbCr)
          tString = Replace(tString, tDelimOld, tDelimNew)
      Next tDelimOld
      
      ' Remove duplicate delimiters
      tString = Replace(tString, tDelimNew & tDelimNew, tDelimNew)
      
      ' Split ;)
      tResult = Split(tString , tDelimNew)
      

      【讨论】:

      • 简单但超级高效!
      【解决方案3】:

      前面的答案很好,但是如果字符串中有背靠背的字符要拆分,例如拆分“您好,先生!您今天好吗?”,您会遇到麻烦。在所有标点符号和空格上。在这种情况下,您会在 Hello 和 Sir 之间得到一个空白字符串。

      为了处理这种情况,Chip Pearson 提供了一个很棒的 VBA 函数供使用: http://www.cpearson.com/excel/splitondelimiters.aspx

      【讨论】:

        【解决方案4】:

        (目前)不允许发表评论,但使用 TRIM 消除双空格的建议尚不完全清楚。 VBA 中的 TRIM 函数只删除前导和尾随空格。它不会触及字符串内的双空格。为此,您必须使用工作表功能。

        【讨论】:

          【解决方案5】:

          我要补充一点,我快速查看了 Chip Pearson 的答案,并认为它可以在性能方面有所改进,所以我编写了自己的,似乎快了 40%(请随意测试自己)。它更快(1.0E-5 vs 1.7E-5 每周期秒数),因为它使用字节数组而不是实际字符来比较值。这是返回像 Chip Pearson 的字符串数组的函数:

          Function SplitMultiDelims2(Text As String, DelimChars As String) As String()
              '''
              'Function to split a string at multiple charachters
              'Use like SplitMultiDelims2("This:is-a,test string", ":-,")
              'Returns an array, in that example SplitMultiDelims2("This:is-a,test string", ":-,")(4) would be "test string"
              '''
              Dim bytes() As Byte
              Dim delims() As Byte
              Dim i As Long, aub As Long, ub As Long
              Dim stack As String
              Dim t() As String
              Dim tLen As Long
              tLen = Len(Text)
              If tLen = 0 Then
                  Exit Function
              End If
              ReDim t(1 To tLen)                           'oversize array to avoid Redim Preserve too often
              bytes = StrConv(Text, vbFromUnicode)
              delims = StrConv(DelimChars, vbFromUnicode)
              ub = UBound(bytes)
              For i = 0 To ub
                  If Contains(delims, bytes(i)) Then
                      aub = aub + 1
                      t(aub) = stack
                      stack = ""
                  Else
                      stack = stack & Chr(bytes(i))
                  End If
              Next i
              t(aub + 1) = stack
              ReDim Preserve t(1 To aub + 1)               'Works marginally faster if you delete this line,
              'however it returns an oversized array (which is a problem if you use UBOUND of the result,
              'but fine if you are just looking up an indexed value like the 5th string)
              SplitMultiDelims2 = t
          End Function
          
          'and a 2nd function called by the first one
          Function Contains(arr, v As Byte) As Boolean     'checks if Byte v is contained in Byte array arr
              Dim rv As Boolean, lb As Long, ub As Long, i As Long
              lb = LBound(arr)
              ub = UBound(arr)
              For i = lb To ub
                  If arr(i) = v Then
                      rv = True
                      Exit For
                  End If
              Next i
              Contains = rv
          End Function
          

          这是测试日志(他的是SplitMultiDelims,我的是SplitMultiDelims2)

          > SplitMultiDelims: 1.76105267188204E-05s per cycle 'this is the important figure
          > i = 568064 iterations in 10.00390625 seconds
          >Test completed: 08/06/2017 10:23:22
          > SplitMultiDelims2: 1.05756701906142E-05s per cycle
          >i = 947044 iterations in 10.015625 seconds
          >Test completed: 08/06/2017 10:23:32
          > SplitMultiDelims2: 1.04176859354441E-05s per cycle
          >i = 960656 iterations in 10.0078125 seconds
          >Test completed: 08/06/2017 10:23:54
          > SplitMultiDelims: 1.76228941673255E-05s per cycle
          >i = 567887 iterations in 10.0078125 seconds
          >Test completed: 08/06/2017 10:24:04
          

          双向奔跑以避免记忆书写障碍

          下面的测试代码使用Timer,所以并不过分精确,但足以证明差异

          Sub testSplit()
              Dim t As Double, dt As Double
              Dim s As String
              Dim i As Long
              t = Timer: i = 0: dt = 0: s = ""
              Do Until dt > 10                             'loop for 10 seconds
                  s = SplitMultiDelims("This:is-a,test string", ":-,")(1)
                  dt = Timer - t
                  i = i + 1
              Loop
              Debug.Print "SplitMultiDelims: " & dt / i & "s per cycle" & vbCrLf & "i = " & i; " iterations in " & dt; " seconds" & vbCrLf & "Test completed: " & Now
              t = Timer: i = 0: dt = 0: s = ""
              Do Until dt > 10                             'loop for 10 seconds
                  s = SplitMultiDelims2("This:is-a,test string", ":-,")(1)
                  dt = Timer - t
                  i = i + 1
              Loop
              Debug.Print "SplitMultiDelims2: " & dt / i & "s per cycle" & vbCrLf & "i = " & i; " iterations in " & dt; " seconds" & vbCrLf & "Test completed: " & Now
          End Sub
          

          【讨论】:

            【解决方案6】:

            在这种情况下你可以这样做

                newString = Replace(origString, "-", " ")
                newString2 = replace(newstring, "  " , " ")
                newArray = SPlit(newString, " ")
            

            【讨论】:

            • 如果你想避免双重空格,你可以使用修剪功能
            • Trim 删除尾随和前导空格
            猜你喜欢
            • 1970-01-01
            • 2012-12-27
            • 2010-10-13
            • 1970-01-01
            • 2012-05-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-10
            相关资源
            最近更新 更多