2014-05-20 258 views
1

如果我有这样的字符串:用字符串拆分字符串?

Dim someStr As String 
someStr = "NODE TEST    ACCESS" 

我想用两个空格分割的字符串。它看起来像Split()函数接受一个字符,而不是一个完整的字符串分裂。

什么是最简单的方法来分割一个字符串的字符串(在这种情况下两个空格)?由两个或更多的空间分裂很好。我不打算在两个分裂。

+0

你的意思是两个空格或两个以上的空间?在下面看到我对lardymonkey的回答的评论。 – BobRodes

+0

@BobRodes两个或更多,但不能保证它会超过2或3个空格。 – JBurace

+0

为了完全清楚,那么,是否要将每两个空格拆分为一个单独的元素,或者是否希望使用任何数量的空格作为单个分隔符? – BobRodes

回答

1

如果你不需要让你可以尝试使用替代命令与另一单个字符每两个字符,你可以

Dim someStr As String 
Dim someArray() as String 

someStr = "NODE TEST    ACCESS" 
someArray = split(Replace$(someStr," ","|"),"|") 
+0

有趣的想法,但如果你有十个空间,你会得到五个|字符,并获得一些数组值和空字符串。我怀疑OP没有很清楚地解释自己,意味着两个或两个以上的空间。他的“完整的字符串”让我更加怀疑。 – BobRodes

2

确定拆分更换空间,得到一些澄清后OP的要求,我们需要扩大lardymonkey的想法。所以:

Dim someStr As String 
Dim someArray() as String 
Dim cLen As Integer 'Keep a count of the current characters in the string 

someStr = "NODE TEST    ACCESS" 

'Strip off one space at a time from groups of >2 spaces 
Do 
    cLen = Len(someStr) 
    someStr = Replace(someStr, Space$(3), Space$(2)) 
Loop Until cLen = Len(someStr) 'No more replacements were made in the current iteration 

'Now you can use lardymonkey's idea 
someArray = Split(Replace$(someStr," ","|"),"|") 
+0

我认为你的意思是'Space $(3),Space $(2)',而不是'Spaces(3),Spaces(2)'? –

+0

糟糕!我其实是指空间功能。之后我通常不会使用$;不好的习惯,因为VB在内部使用Variant的时候真的不行。谢谢马克,我解决了它。 – BobRodes

1

到lardymonkey andBoBrodes

的答案稍有变化,为什么你会用空格替换成“|” ?原始字符串可能包含“|”本身这会产生意外结果

,最好由单一的货物更换双位:

Private Sub Command1_Click() 
    Dim someStr As String 
    Dim strArray() As String 
    someStr = "NODE TEST    ACCESS" 
    someStr = RemoveDouble(someStr, " ") 
    strArray = Split(someStr, " ") 
End Sub 

Private Function RemoveDouble(strSource As String, strRemove As String) 
    Dim strReturn As String 
    Dim strDouble As String 
    strDouble = strRemove & strRemove 
    strReturn = Replace(strSource, strDouble, strRemove) 
    Do While InStr(strReturn, strDouble) > 0 
    strReturn = Replace(strReturn, strDouble, strRemove) 
    Loop 
    RemoveDouble = strReturn 
End Function 
2

如果我读了OP的qusetion正确,他们希望在不返回渐渐空虚结果分割字符串。使用正则表达式大大简化了这一点。首先添加对的引用Microsoft VBScript正则表达式5.5。然后,您可以根据您的具体需求调整以下功能。

请注意,示例中没有错误处理。

Private Function SplitString(ByVal vPattern As String, ByVal vText As String, ByRef Result() As String) As Integer 
    Dim regex As New RegExp 
    Dim colMatches As MatchCollection 
    Dim intMatchCount As Integer 
    Dim i As Integer 

    intMatchCount = 0 
    regex.Pattern = vPattern 
    regex.Global = True 
    regex.IgnoreCase = True 
    Set colMatches = regex.Execute(vText) 
    If regex.Test(vText) = True Then 
     intMatchCount = colMatches.Count 
     ReDim Result(0 To intMatchCount) 
     For i = 0 To intMatchCount - 1 
      Result(i) = colMatches(i).Value 
     Next i 
     Set colMatches = Nothing ' I don't know if this is needed, but playing it safe 
    End If 
    Set regex = Nothing ' I don't know if this is needed, but playing it safe 

    SplitString = intMatchCount 

End Function 

要使用该功能,请在窗体中添加多行文本框和命令按钮并粘贴到以下代码中。

Private Sub Command1_Click() 
    Dim aryMatches() As String 
    Dim i As Integer 
    Dim strPattern As String 
    Dim strText As String 

    Text1.Text = "" 
    strPattern = "\w+" 
    strText = "NODE TEST    ACCESS" 
    If SplitString(strPattern, strText, aryMatches) > 0 Then 
     For i = LBound(aryMatches) To UBound(aryMatches) 
      Text1.SelText = aryMatches(i) & vbCrLf 
      Text1.SelStart = Len(Text1.Text) 
     Next i 
    End If 

End Sub 
1

这次是一个完全不同的答案 - 使用更“原始”的VB字符串函数。如果你对这样的事情感兴趣,这大概是Bob Rhode的答案的两倍。

本质上,我移过字符串,注意两个或多个空格的位置,然后一次移动一个字符,直到找到非空格。使用这些信息,我们可以从字符串中的正确位置提取子字符串,并将它们复制到预先分配的字符串数组中。我分配在64块阵列如果我们去上面的数组中元素的个数,我们以64

Private Function SplitOnMultiSpaces2(ByVal someStr As String) As String() 

    Const someStringsChunkLen As Long = 64 
    Dim someStringLen   As Long 
    Dim someStrings()   As String 
    Dim someStringsIndex  As Long 
    Dim multiSpacePos   As Long 
    Dim nextPos     As Long 

    ' Cache the length of the string. 
    someStringLen = Len(someStr) 

    ' Allocate one chunk of elements initially. 
    ReDim someStrings(0 To someStringsChunkLen - 1) 

    ' Point to the first element in the array. 
    someStringsIndex = 0 

    ' Find the first position of more than 1 space. 
    multiSpacePos = InStr(1, someStr, " ", vbBinaryCompare) 

    ' Special case. If no multi spaces were found, then simply return a single string in the array. 
    If multiSpacePos = 0 Then 
     someStrings(0) = someStr 
    Else 
     ' Point the beginning of the next string to the first character in <someStr>. 
     nextPos = 1 
     Do 
      ' Copy the "next string" into the next available array element. 
      someStrings(someStringsIndex) = Mid$(someStr, nextPos, multiSpacePos - nextPos) 

      ' Move to the second space in the multi-spaces, and iterate until we find a non-space (space = ASCII 32). 
      nextPos = multiSpacePos + 1 
      Do 
       If nextPos = someStringLen Then 
        Exit Do 
       End If 
       nextPos = nextPos + 1 
      Loop While AscW(Mid$(someStr, nextPos, 1)) = 32 

      ' We now pointing to the beginning of the next string - or at the end of the string. 
      ' Look for the next multi space. 
      multiSpacePos = InStr(nextPos, someStr, " ", vbBinaryCompare) 

      ' Point to the next array element. 
      someStringsIndex = someStringsIndex + 1 
      ' If this array element points beyond the current upper bound of the array, then add another chunk to the array. 
      ' We look at the remainder from dividing <someStringsIndex> by <someStringsChunkLen>. 
      ' For instance, if this is element 64, then this is 64/64 = 1 remainder 0. 
      ' We can use this simple test because we only resize upwards. 
      If (someStringsIndex Mod someStringsChunkLen) = 0 Then 
       ' e.g. resize upper bound to 64 + 64 - 1 = 127. 
       ReDim Preserve someStrings(0 To someStringsIndex + someStringsChunkLen - 1) 
      End If 
     Loop Until multiSpacePos = 0 

     ' If we aren't at the end of the string, then copy the remaining values. 
     If nextPos <> someStringLen Then 
      someStrings(someStringsIndex) = Mid$(someStr, nextPos) 
     End If 
    End If 

    ' Resize down to the proper size. 
    ReDim Preserve someStrings(0 To someStringsIndex) 

    ' Return the string array. 
    SplitOnMultiSpaces2 = someStrings() 

End Function 
+0

快两倍,真的吗?有趣。你有基准吗?我不是要求防守的;我真的很感兴趣。 – BobRodes

2

另一块重新分配,它只是使用正则表达式与任何字符替换两个或多个空格然后分割该角色。

  1. 添加对“Microsoft VBScript正则表达式”的引用。
  2. 做这样的事情:

    Dim a() As String 
    
    With New RegExp 
        .Pattern = "\s{2,}" 
        a = Split(.Replace(someStr, "~"), "~") 
    End With 
    
+0

只需使用'ChrW(&HE1B6)'而不是'〜'或unicode的*私有使用区域(PUA)*中的任何内容来避免冲突。 – wqw

+0

@wqw当然,你是对的。我只是为了演示目的而保持简单。 – Bond