2011-10-06 29 views

Odpowiedz

23

Można najpierw zrobić REPLACE na strunie, a potem zrobić dzielone: ​​

newString = Replace(origString, "-", " ") 
newArray = SPlit(newString, " ") 
3

poprzednią odpowiedź jest dobra, ale spowoduje, aby mieć kłopoty, jeśli nie są z powrotem do tyłu znaki mają być rozdzielone na tym są w Ciągu, takie jak podział "Cześć, Sir, jak się masz dzisiaj?" na wszystkich interpunkcji i spacje. W takim przypadku otrzymasz pusty ciąg pomiędzy Hello i Sir.

Aby obsługiwać ten scenariusz Chip Pearson stanowi doskonałą funkcję VBA użycia: http://www.cpearson.com/excel/splitondelimiters.aspx

0

w takim przypadku można zrobić

newString = Replace(origString, "-", " ") 
    newString2 = replace(newstring, " " , " ") 
    newArray = SPlit(newString, " ") 
+0

jeśli chcesz uniknąć podwójnej przestrzeni, możesz użyć funkcji przycinania – juanora

1

Nie wolno komentować (jeszcze), ale sugestia wykorzystania TRIM wyeliminowanie podwójnej przestrzeni nie jest w pełni jasne. Funkcja TRIM w VBA usuwa tylko spacje wiodące i końcowe. Nie dotyka podwójnych spacji w ciągu znaków. Do tego celu musiałbyś użyć funkcji arkusza roboczego.

0

Dodam, że rzuciłem okiem na odpowiedź Chipa Pearsona i pomyślałem, że można ją poprawić nieco pod względem wydajności, więc napisałem własną, która wydaje się być o 40% szybsza (nie krępuj się przetestować siebie). Jest szybszy (1.0E-5 vs 1.7E-5 sekund na cykl), ponieważ wykorzystuje tablice bajtów zamiast rzeczywistych znaków do porównywania wartości. Oto funkcja, która zwraca tablicę ciągów jak Chip Pearsona:

Function SplitMultiDelims2(Text As String, DelimChars As String) As String() 
''' 
'Function to split a string at multiple charachters 
'Use like SplitMultiDelims2("This:is-a,test string", ":-,") 
'Returns an array, in that example SplitMultiDelims2("This:is-a,test string", ":-,")(4) would be "test string" 
''' 
Dim bytes() As Byte 
Dim delims() As Byte 
Dim i As Long, aub As Long, ub As Long 
Dim stack As String 
Dim t() As String 
Dim tLen As Long 
tLen = Len(Text) 
If tLen = 0 Then 
    Exit Function 
End If 
ReDim t(1 To tLen) 'oversize array to avoid Redim Preserve too often 
bytes = StrConv(Text, vbFromUnicode) 
delims = StrConv(DelimChars, vbFromUnicode) 
ub = UBound(bytes) 
For i = 0 To ub 
    If Contains(delims, bytes(i)) Then 
     aub = aub + 1 
     t(aub) = stack 
     stack = "" 
    Else 
     stack = stack & Chr(bytes(i)) 
    End If 
Next i 
t(aub + 1) = stack 
ReDim Preserve t(1 To aub + 1) 'Works marginally faster if you delete this line, 
    'however it returns an oversized array (which is a problem if you use UBOUND of the result, 
    'but fine if you are just looking up an indexed value like the 5th string) 
SplitMultiDelims2 = t 
End Function 

'and a 2nd function called by the first one 
Function Contains(arr, v As Byte) As Boolean 'checks if Byte v is contained in Byte array arr 
Dim rv As Boolean, lb As Long, ub As Long, i As Long 
    lb = LBound(arr) 
    ub = UBound(arr) 
    For i = lb To ub 
     If arr(i) = v Then 
      rv = True 
      Exit For 
     End If 
    Next i 
    Contains = rv 
End Function 

Oto dziennika testu (jego jest SplitMultiDelims, kopalnia SplitMultiDelims2)

> SplitMultiDelims: 1.76105267188204E-05s per cycle 'this is the important figure 
> i = 568064 iterations in 10.00390625 seconds 
>Test completed: 08/06/2017 10:23:22 
> SplitMultiDelims2: 1.05756701906142E-05s per cycle 
>i = 947044 iterations in 10.015625 seconds 
>Test completed: 08/06/2017 10:23:32 
> SplitMultiDelims2: 1.04176859354441E-05s per cycle 
>i = 960656 iterations in 10.0078125 seconds 
>Test completed: 08/06/2017 10:23:54 
> SplitMultiDelims: 1.76228941673255E-05s per cycle 
>i = 567887 iterations in 10.0078125 seconds 
>Test completed: 08/06/2017 10:24:04 

Run w obu kierunkach, aby uniknąć pisania pamięci niekorzystnie wpływa

poniżej kod

test wykorzystuje Timer więc niezbyt precyzyjne, ale wystarczająco dobry, aby wykazać różnicę

Sub testSplit() 
Dim t As Double, dt As Double 
Dim s As String 
Dim i As Long 
t = Timer: i = 0: dt = 0: s = "" 
Do Until dt > 10 'loop for 10 seconds 
    s = SplitMultiDelims("This:is-a,test string", ":-,")(1) 
    dt = Timer - t 
    i = i + 1 
Loop 
Debug.Print "SplitMultiDelims: " & dt/i & "s per cycle" & vbCrLf & "i = " & i; " iterations in " & dt; " seconds" & vbCrLf & "Test completed: " & Now 
t = Timer: i = 0: dt = 0: s = "" 
Do Until dt > 10 'loop for 10 seconds 
    s = SplitMultiDelims2("This:is-a,test string", ":-,")(1) 
    dt = Timer - t 
    i = i + 1 
Loop 
Debug.Print "SplitMultiDelims2: " & dt/i & "s per cycle" & vbCrLf & "i = " & i; " iterations in " & dt; " seconds" & vbCrLf & "Test completed: " & Now 
End Sub 
1

Aby podzielić za pomocą kilku różnych ograniczników; wymień ograniczniki w tablicy, zamień je na pętlę for, a następnie podziel:

For Each tSep In Array(";", " ", ".", "<==", ":", vbCr) 
    val1 = Replace(val1, tSép, "°") 
Next tSep 
tab1 = Split(val1, "°") 
Powiązane problemy