如何分割一个string与多个维度在VBA的Excel中?

我想用Excel VBA分割一个string与多个delimeters。 其中一个string是:

d1-d2 d3 d4 

我们有一个短划线和一个空格作为两个分隔符。 我尝试了splitfunction,但它只有一个分隔符。

你可以先对string进行REPLACE ,然后进行分割:

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

以前的答案是好的,但是如果在string中有背对背的字符被拆分,比如分裂“你好,先生,你今天过得怎么样? 在所有的标点符号和空格上。 在这种情况下,您将在Hello和Sir之间得到一个空白string。

为了处理这种情况,Chip Pearson提供了一个很好的VBAfunction: http : //www.cpearson.com/excel/splitondelimiters.aspx

不允许评论(但),但使用TRIM消除双重空间的build议不完全清楚。 VBA中的TRIMfunction仅删除前导和尾随空格。 它不会触及string中的双重空格。 你将不得不使用工作表function。

在这种情况下你可以做

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

我会补充一点,我快速浏览了Chip Pearson的答案,并认为在性能方面可以稍微提高一点,所以我编写了自己的程序,似乎快了大约40%(可以自由testing)。 它更快( 1.0E-51.7E-5秒每个周期),因为它使用字节数组而不是实际字符比较值。 这里是返回像Chip Pearson's这样的string数组的函数:

 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 

这里是testing日志(他是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 

双向运行以避免内存写入障碍

下面的testing代码使用Timer所以不要过分精确,但足以certificate差异

 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