如何在VBA中将字符串分割成多个字符

时间:2018-11-04 20:29:16

标签: vba split

在C#中,可以很容易地将一个拆分字符串拆分成多个字符,一个提供了一个拆分字符数组。我想知道在VBA中实现此目标的最佳方法是什么。我通常使用VBA.Split,但要分割多个字符,需要钻取结果并再分割元素。然后必须重新排列数组等的尺寸。非常痛苦。

约束

仅VBA回应。如果需要,可以使用.NET集合类(yes they are creatable and callable in VBA)。如果需要,可以使用JSON,XML作为分割段列表的容器。如果愿意,可以使用不起眼的VBA.Collection类,甚至可以使用Scripting.Dictionary。如果愿意,您甚至可以使用伪造的记录集。

我完全知道可以编写一个.NET程序集来调用.NET String.Split方法,并通过COM接口将程序集公开给VBA,但这是挑战所在。

2 个答案:

答案 0 :(得分:3)

在尝试分割空格之前,我用空格替换了所有其他字符。 (所以我有点作弊。)

Private Function SplitByMoreThanOneChars(ByVal sLine As String)
    '*
    '* Brought to you by the Excel Development Platform Blog
    '* http://exceldevelopmentplatform.blogspot.com/2018/11/
    '*
    '* Don't get excited, this splits by spaces only
    '* we fake splitting by multiple characters by replacing those characters
    '* with spaces 
    '*
    Dim vChars2 As Variant
    vChars2 = Array(" ", "<", ">", "[", "]", "(", ")", ";")

    Dim sLine2 As String
    sLine2 = sLine

    Dim lCharLoop As Long
    For lCharLoop = LBound(vChars2) To UBound(vChars2)
        Debug.Assert Len(vChars2(lCharLoop)) = 1
        sLine2 = VBA.Replace(sLine2, vChars2(lCharLoop), " ")
    Next

    SplitByMoreThanOneChars = VBA.Split(sLine2)


End Function

答案 1 :(得分:3)

使用正则表达式应该相当容易。如果您对传递的字符取反进行拆分,则这些匹配将成为输出数组的成员。这样做的好处是输出数组仅需要调整一次大小,因为您可以获得RegExp返回的匹配计数。该模式的构建非常简单-可以归结为类似[^abc]+的样式,其中'a','b'和'c'是要分割的字符。准备表达式所需要做的唯一一件事就是在正则表达式中转义几个在该上下文中具有特殊含义的字符(我可能忘记了一些):

Private Function BuildRegexPattern(ByVal inputString As String) As String
    Dim escapeTargets() As String
    escapeTargets = VBA.Split("- ^ \ ]")

    Dim returnValue As String
    returnValue = inputString

    Dim idx As Long
    For idx = LBound(escapeTargets) To UBound(escapeTargets)
        returnValue = Replace$(returnValue, escapeTargets(idx), "\" & escapeTargets(idx))
    Next
    BuildRegexPattern = "[^" & returnValue & "]+"
End Function

一旦有了模式,只需简单地确定数组的大小并迭代匹配项以分配它们(加上一些其他特殊情况处理等)即可。

Public Function MultiSplit(ByVal toSplit As String, Optional ByVal delimiters As String = " ") As String()
    Dim returnValue() As String

    If toSplit = vbNullString Then
        returnValue = VBA.Split(vbNullString)
    Else
        With New RegExp
            .Pattern = BuildRegexPattern(IIf(delimiters = vbNullString, " ", delimiters))
            .MultiLine = True
            .Global = True
            If Not .Test(toSplit) Then
                'Only delimiters.
                ReDim returnValue(Len(toSplit) - 1)
            Else
                Dim matches As Object
                Set matches = .Execute(toSplit)
                ReDim returnValue(matches.Count - 1)
                Dim idx As Long
                For idx = LBound(returnValue) To UBound(returnValue)
                    returnValue(idx) = matches(idx)
                Next
            End If
        End With
    End If

    MultiSplit = returnValue
End Function