将字符串拆分为字符数组?

36

如何将VBA字符串分割成字符数组?

我尝试了Split(my_string, ""),但是这并没有起作用。

7个回答

56

最安全和最简单的方法就是循环;

Dim buff() As String
ReDim buff(Len(my_string) - 1)
For i = 1 To Len(my_string)
    buff(i - 1) = Mid$(my_string, i, 1)
Next

如果你能保证只使用ANSI字符,你可以这样做:

Dim buff() As String
buff = Split(StrConv(my_string, vbUnicode), Chr$(0))
ReDim Preserve buff(UBound(buff) - 1)

如果当前区域设置不是1033,则后一种方法可能无法正常工作(即使只有ASCII字符,也“是一个丑陋的Hack,不应该使用”)。 - user202729
在一个百万字符的字符串上尝试这两种方法,我发现第一种方法大约快了7倍。它甚至比使用split()的方法更快:即使只是运行split()这一行,在分隔符放置好后,测试时间也更长。 - Mark E.

17

您可以将字符串分配给字节数组(反之亦然)。每个字符的结果是2个数字,因此Xmas转换为包含{ 88,0,109,0,97,0,115,0 }的字节数组
或者您可以使用StrConv

Dim bytes() as Byte
bytes = StrConv("Xmas", vbFromUnicode)

使用这种方法可以得到{88,109,97,115},但是在这种情况下你不能将字节数组重新分配给一个字符串。
你可以使用Chr()函数将字节数组中的数字转换回字符。


10

以下是使用VBA的另一种方法。

Function ConvertToArray(ByVal value As String)
    value = StrConv(value, vbUnicode)
    ConvertToArray = Split(Left(value, Len(value) - 1), vbNullChar)
End Function
Sub example()
    Dim originalString As String
    originalString = "hi there"
    Dim myArray() As String
    myArray = ConvertToArray(originalString)
End Sub

1
@PatrickHonorez 謝謝。也許當時我不知道那件事情。 - Daniel
1
不必使用Split(Left(value, Len(value) - 1), vbNullChar),你可以使用Split(value, vbNullChar, Len(value))。这样代码更简洁,字符串操作更少。仍然是好的代码。 - Tom Collins
@PatrickHonorez 这是错误的。字符串是不可变的。你可以通过显式传递 ByRef 来测试这一点。它不会修改原始字符串。 - SSlinky
@Sam V:如果你将一个值为“dog”的变量myString作为“strArgument”传递到函数中,并且函数的主体仅包含一行代码strArgument =“cat”,那么在运行函数后,你会发现myString现在等于“cat”。我很好奇你测试了什么,如果你发现了其他结果。 - Mark E.
@MarkE。好的,我很高兴被纠正了!简短的回答是我没有测试过。自信地错误了。也许我被Python中的行为所困惑了。 - SSlinky
显示剩余4条评论

8

1
这很整洁且相当快,但正如源代码所指出的那样,它确实在数组末尾留下了一个额外的空白。 - Mark E.
这应该是最佳解决方案,除非空数组插槽存在更多缺点...它在简单文本上运行良好。 - Justin Doward
好的解决方案。只需在开头将a声明为变量,并在计算a后添加一行ReDim Preserve a(UBound(a) - 1) - Alper

0

尝试使用Rara的这个小代码:

Function charSplitMulti(TheString As Variant, SplitLen As Long) As Variant
    'Defining a temporary array.
    Dim TmpArray() As String
    'Checking if the SplitLen is not less than one. if so the function returns the whole string without any changing.
    SplitLen = IIf(SplitLen >= 1, SplitLen, Len(TheString))
    'Redefining the temporary array as needed.
    ReDim TmpArray(Len(TheString) \ SplitLen + IIf(Len(TheString) Mod SplitLen <> 0, 1, 0))
    'Splitting the input string.
    For i = 1 To UBound(TmpArray)
        TmpArray(i) = Mid(TheString, (i - 1) * SplitLen + 1, SplitLen)
    Next
    'Outputing the result. 
    charSplitMulti = TmpArray
End Function

1
恭喜你的第一个答案!但请检查一下你的答案是否有任何帮助或益处,它是否提供了新的算法?是否更加优化,或者代码更加简洁? - 2oppin

0

问题在于VB中没有内置的方法(或者至少我们没有找到)来做这个。然而,有一种方法可以在空格上分割字符串,所以我只需重新构建字符串并添加空格...

Private Function characterArray(ByVal my_string As String) As String()
  'create a temporary string to store a new string of the same characters with spaces
  Dim tempString As String = ""
  'cycle through the characters and rebuild my_string as a string with spaces 
  'and assign the result to tempString.  
  For Each c In my_string
     tempString &= c & " "
  Next
  'return return tempString as a character array.  
  Return tempString.Split()
End Function

当您已经逐个字符地遍历字符串时,为什么不只是构建这些字符的数组(如在此帖子之前已经存在3年的接受答案中),而不是构建另一个更长的字符串,然后使用内部函数逐个字符地遍历该字符串以构建数组?猜猜当my_string包含空格时会发生什么。此外,问题是关于VBA而不是VB的(For Each c In my_string在VBA中不起作用)。此外,VB有my_string.ToCharacterArray() - Paul Sinclair

0
将字符串分割为任意长度的子字符串数组:
Function charSplitMulti(s As Variant, splitLen As Long) As Variant
    
        Dim padding As Long: padding = 0
        Dim l As Long: l = 0
        Dim v As Variant
        
        'Pad the string so it divides evenly by
        ' the length of the desired sub-strings
        Do While Len(s) Mod splitLen > 0
            s = s & "x"
            padding = padding + 1
        Loop
        
        'Create an array with sufficient
        ' elements to hold all the sub-strings
        Do Until Len(v) = (Len(s) / splitLen) - 1
            v = v & ","
        Loop
        v = Split(v, ",")
        
        'Populate the array by repeatedly
        ' adding in the first [splitLen]
        ' characters of the string, then
        ' removing them from the string
        Do While Not s Like ""
            v(l) = Mid(s, 1, splitLen)
            s = Right(s, Len(s) - splitLen)
            l = l + 1
        Loop
        
        'Remove any padding characters added at step one
        v(UBound(v)) = Left(v(UBound(v)), Len(v(UBound(v))) - padding)
        
        'Output the array
        charSplitMulti = v
    
    End Function

你可以将字符串作为字符串传递给它:

Sub test_charSplitMulti_stringInput()

    Dim s As String: s = "123456789abc"
    Dim subStrLen As Long: subStrLen = 4
    Dim myArray As Variant
    
    myArray = charSplitMulti(s, subStrLen)
    
    For i = 0 To UBound(myArray)
        MsgBox myArray(i)
    Next

End Sub

...或者已经声明为变量:

Sub test_charSplitMulti_variantInput()

    Dim s As Variant: s = "123456789abc"
    Dim subStrLen As Long: subStrLen = 5
    
    s = charSplitMulti(s, subStrLen)
    
    For i = 0 To UBound(s)
        MsgBox s(i)
    Next

End Sub

如果所需子字符串的长度不能被字符串长度等分,则数组的最上面的元素将会更短。(它将等于 strLength Mod subStrLength。这可能是显而易见的。)

我发现我经常使用它将字符串拆分为单个字符,因此我添加了另一个函数,这样我就可以懒惰并且在这种情况下不必传递两个变量:

Function charSplit(s As Variant) As Variant

    charSplit = charSplitMulti(s, 1)

End Function

Sub test_charSplit()

    Dim s As String: s = "123456789abc"
    Dim myArray As Variant
    
    myArray = charSplit(s)
    
    For i = 0 To UBound(myArray)
        MsgBox myArray(i)
    Next

End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接