0

我写了这个。是的,我知道它是 VB6。是的,它是生产代码,而且,是的,我知道它使用 goto。我是一只懒惰、邪恶的野兽……

所以告诉我(和我们其他人)应该如何写

Public Function SplitString(ByVal sText As Variant) As Variant
    Dim nHere As Long
    Dim cHere As String * 1
    Dim aRes As Variant
    Dim nRes As Long
    Dim bInquote As Boolean
    Dim sString As String
    ReDim aRes(0)
    nHere = 1
    nRes = 0
    Do
    If nHere > Len(sText) Then Exit Do
    cHere = Mid$(sText, nHere, 1)
    If cHere = Chr$(32) Then
        If bInquote Then
        sString = sString & cHere
        GoTo nextChar
        End If
        If sString <> vbNullString Then
        aRes(nRes) = sString
        sString = vbNullString
        nRes = nRes + 1
        ReDim Preserve aRes(nRes)
        End If
        GoTo nextChar
    ElseIf cHere = Chr$(34) Then
        bInquote = Not bInquote
        GoTo nextChar
    Else
        sString = sString & cHere
    End If
nextChar:
    nHere = nHere + 1
    Loop
    If sString <> vbNullString Then
    aRes(nRes) = sString
    End If
    SplitString = aRes
End Function

顺便说一句,它将一个字符串拆分为一个数组。字符串中的元素可以被引用。

4

6 回答 6

6

这很简单:

将“If sString <> vbNullString Then”更改为“ElseIf sString <> vbNullString Then”,删除所有“Goto”并删除“nextChar:”。

Public Function SplitString(ByVal sText As Variant) As Variant
    Dim nHere As Long
    Dim cHere As String * 1
    Dim aRes As Variant
    Dim nRes As Long
    Dim bInquote As Boolean
    Dim sString As String
    ReDim aRes(0)
    nHere = 1
    nRes = 0
    Do
        If nHere > Len(sText) Then Exit Do
        cHere = Mid$(sText, nHere, 1)
        If cHere = Chr$(32) Then
            If bInquote Then
                sString = sString & cHere
            ElseIf sString <> vbNullString Then
                aRes(nRes) = sString
                sString = vbNullString
                nRes = nRes + 1
                ReDim Preserve aRes(nRes)
            End If
        ElseIf cHere = Chr$(34) Then
            bInquote = Not bInquote
        Else
            sString = sString & cHere
        End If

        nHere = nHere + 1
    Loop
    If sString <> vbNullString Then
        aRes(nRes) = sString
    End If
    SplitString = aRes
End Function
于 2009-06-14T13:54:35.000 回答
2

我同意这个特定的逻辑应该使用 Split() 和 Join() 操作清晰而轻松地实现。虽然人们总是可以编写大量的内联代码来提高它们的速度,但有两个理由不这样做:

  • 性能差异可能甚至不会接近 1.5 倍,而且这种逻辑很少在非常大的字符串上使用数百万次。
  • 这样的内联逻辑不仅不透明且难以维护,而且在编写程序时很难在第一次就正确。

例子:

Function SplitString(ByVal Text As String) As String()
    Dim Slices() As String
    Dim UnquotedSlice As Long

    Slices = Split(Text, """")
    For UnquotedSlice = 0 To UBound(Slices) Step 2
        Slices(UnquotedSlice) = Replace$(Slices(UnquotedSlice), " ", vbNullChar)
    Next
    SplitString = Split(Join$(Slices, ""), vbNullChar)
End Function

顺便说一句:感谢任何可以修复本网站在我上面的示例中使用的不正当代码引用标记的人。

编辑:没关系,我眨了眨眼。项目符号列表让解析器一阵痉挛。

于 2009-06-14T15:45:07.263 回答
2

你应该看看这里,了解微妙的优化如何影响这类任务:

http://www.xbeat.net/vbspeed/c_Split.htm

You'll see that amongst those algorithms, there is no best one, but rather some pretty good ones and then some that can really whoop the outlyers a bit better than others.

于 2009-06-16T00:33:55.707 回答
1

我听说一个经验法则说,如果你的 goto 向前跳,它可能没问题。这看起来像是其中一种情况。但是,如果您可以反转谓词的逻辑,则似乎更容易。

于 2009-06-14T15:13:53.047 回答
0

看起来很直接。只需使用 if/else 结构。如果您的代码进入 if 块,它永远不会进入相应的 elseif 或 else 块。首先,您甚至不需要很多 goto 语句。

Public Function SplitString(ByVal sText As Variant) As Variant
    Dim nHere As Long
    Dim cHere As String * 1
    Dim aRes As Variant
    Dim nRes As Long
    Dim bInquote As Boolean
    Dim sString As String
    ReDim aRes(0)
    nHere = 1
    nRes = 0
    Do
        If nHere > Len(sText) Then Exit Do
        cHere = Mid$(sText, nHere, 1)
        If cHere = Chr$(32) Then
            If bInquote Then
                sString = sString & cHere
            ElseIf sString <> vbNullString Then
                aRes(nRes) = sString
                sString = vbNullString
                nRes = nRes + 1
                ReDim Preserve aRes(nRes)
            End If
        ElseIf cHere = Chr$(34) Then
            bInquote = Not bInquote
        Else
            sString = sString & cHere
        End If
        nHere = nHere + 1
    Loop
    If sString <> vbNullString Then
        aRes(nRes) = sString
    End If
    SplitString = aRes
End Function
于 2009-06-14T13:55:12.270 回答
-1

我只是使用 VB6 原生的Split 函数Join 函数。我将把细节留给你,但基本流程是分割空格,然后重新加入引号之间的对象。

我已经好几年没有写过 VB6 了,也没有安装软件(用于调试),所以我不想尝试这个功能。

祝你好运,
弗兰克

于 2009-06-14T14:13:02.600 回答