将一组双引号分隔的名称 - 值对拆分成数组的最简单方法是什么?

时间:2014-01-29 16:04:23

标签: vba excel-vba excel

给定一个包含以下内容的字符串:

property myprop1="test" myprop2="testing again" myprop3="another test"

进入字符串数组的最简单方法是什么:

property
myprop1="test"
myprop2="testing again"
myprop3="another test"

拆分成二维数组会更好:

property
myprop1     test
myprop2     testing again
myprop3     another test

我最初的计划是在字符串上运行带有空格分隔符的split函数。如果名称 - 值对的值部分中没有嵌入空格,这当然可以包含空格。

某些条件: 此代码需要在Excel 2010 VBA中执行。我不想添加第三方引用或一堆工具包。我不是在寻找优雅或IEEE的例子。我需要可维护且易于理解的生产代码。

提前感谢您提供任何帮助!

编辑:'mypropX'的数量是可变的;可能少于或多于三个。 EDIT2:我被告知另一个“差异”。 :)结果myprop的值可能不会被双引号分隔;在这种情况下,它将是一个没有内部空间的单个字母数字字符串。

3 个答案:

答案 0 :(得分:0)

如果你替换('=“','=')那么你可以对'''进行拆分,这应该给你:

property
myprop1=test
myprop2=testing again
myprop3=another test

这假设“引号内部没有”(无论如何都会使大多数尝试解析)。

然后你可以在'='上拆分这个数组中的项目以进入一个2元素数组。为了考虑可能的=在值内,将Split()上的Limit参数设置为2。

编辑: 我感觉很慷慨 - 这里有一些代码 - 添加你自己的错误处理!

Public Sub ParseNVPs(ByVal str As String, ByRef ReturnArray() as String)
Dim SplitArray() As String
Dim LineArray() As String
Dim i As Integer

    str = Replace(str, "=""", "=")
    SplitArray = Split(str, """ ")

    ReDim ReturnArray(UBound(SplitArray), 1)

    For i = 0 To UBound(SplitArray)
        LineArray = Split(SplitArray(i), "=", 2)
        ReturnArray(i, 0) = LineArray(0)
        ReturnArray(i, 1) = LineArray(1)
    Next i

End Sub

答案 1 :(得分:0)

试试这个

Sub Test()
    Dim strVar, Arr1, Arr2()

    strVar = "property myprop1=""test"" myprop2=""testing again"" myprop3=""another test"""

    Arr1 = Split(Mid(strVar, InStr(1, strVar, " ") + 1), """ ")
    ReDim Arr2(UBound(Arr1) + 1)
    Arr2(0) = Mid(strVar, 1, InStr(1, strVar, " ")) 'store the first string, i.e. property

    'store the data with double quotes
    For i = 0 To UBound(Arr1) - 1
        Arr2(i + 1) = Arr1(i) & """"
    Next
    'store the last string
    Arr2(i + 1) = Arr1(i)

    For i = 0 To UBound(Arr2)
        MsgBox Arr2(i)
    Next
End Sub

答案 2 :(得分:0)

这就是我想出的。这不是优雅,但它完成了工作。感谢输入人员,这非常有帮助。

'split name value pairs into array
strWorkString = schematicLines(lngValuePosition)
lngStartPosition = 1
lngEndPosition = 1
fStartQuote = False
f1stWordDone = False
ReDim strWorkArray(0) As String

For lngLoopCounter = 1 To Len(strWorkString) - 1

    strCurrentCharacter = Mid(strWorkString, lngLoopCounter, 1)

    Select Case True
        Case (strCurrentCharacter = " " And Not fStartQuote)   'space and we aren't in a value
            If (f1stWordDone) Then
                ReDim Preserve strWorkArray(UBound(strWorkArray) + 1) As String
            End If

            lngEndPosition = lngLoopCounter
            strWorkArray(UBound(strWorkArray)) = Trim(Mid(strWorkString, lngStartPosition, lngEndPosition - lngStartPosition))
            lngStartPosition = lngEndPosition + 1
            lngEndPosition = lngStartPosition
            f1stWordDone = True

        Case strCurrentCharacter = Chr$(34) 'double quote

            If fStartQuote Then   'in a value
                'store the nvp
                lngEndPosition = lngLoopCounter

                ReDim Preserve strWorkArray(UBound(strWorkArray) + 1) As String
                strWorkArray(UBound(strWorkArray)) = Trim(Mid(strWorkString, lngStartPosition, lngEndPosition - lngStartPosition + 1))

                lngLoopCounter = lngLoopCounter + 1 'skip the space
                lngStartPosition = lngLoopCounter
                lngEndPosition = lngStartPosition

                fStartQuote = False
            Else
                fStartQuote = True
            End If
    End Select

Next lngLoopCounter

' get the last nvp
ReDim Preserve strWorkArray(UBound(strWorkArray) + 1) As String
strWorkArray(UBound(strWorkArray)) = Mid(strWorkString, lngStartPosition, lngLoopCounter - lngStartPosition + 1)