Excel VBA를 사용하여 여러 delimeter로 문자열을 분할하고 싶습니다. 문자열 중 하나는 다음과 같습니다.vba에서 여러 delimeter로 문자열을 분할하는 방법은 무엇입니까?
d1-d2 d3 d4
두 개의 구분 기호로 대시와 공백이 있습니다. 나는 split
함수를 시도했지만 한 delimeter 만 사용한다.
Excel VBA를 사용하여 여러 delimeter로 문자열을 분할하고 싶습니다. 문자열 중 하나는 다음과 같습니다.vba에서 여러 delimeter로 문자열을 분할하는 방법은 무엇입니까?
d1-d2 d3 d4
두 개의 구분 기호로 대시와 공백이 있습니다. 나는 split
함수를 시도했지만 한 delimeter 만 사용한다.
먼저 첫 번째 문자열에 REPLACE
을 한 후 분할 할 수있는 :
newString = Replace(origString, "-", " ")
newArray = SPlit(newString, " ")
이전의 대답은 좋다, 그러나 분할되는 문자를 다시 다시이있는 경우는 문제가 원인이됩니다 "안녕, 선생님! 어떻게 지내니, 오늘 요?" 모든 구두점 및 공백에 적용됩니다. 이 경우 Hello와 Sir 사이에 빈 문자열이 생깁니다.
는 칩 피어슨이 사용하기에 좋은 VBA 기능을 제공하는이 시나리오를 처리하려면 http://www.cpearson.com/excel/splitondelimiters.aspx하는 경우에 당신이 할 수있는
newString = Replace(origString, "-", " ")
newString2 = replace(newstring, " " , " ")
newArray = SPlit(newString, " ")
되지 않음 이에 TRIM을 사용하는 제안 이중 공간을 제거하는 것은 완전히 명확하지 않습니다. VBA의 TRIM 함수는 선행 및 후행 공백 만 삭제합니다. 문자열 안의 이중 공백은 만지지 않습니다. 이를 위해서는 워크 시트 기능을 사용해야합니다.
나는 칩 피어슨의 대답을 간략하게 살펴보고 성능면에서 약간 개선 될 수 있다고 생각하므로 약 40 % 더 빨라 보이는 내 자신의 글을 썼다. 당신 자신). 실제 문자가 아닌 바이트 배열을 사용하여 값을 비교하기 때문에 빠릅니다 (주기 당 1.0E-5
대 1.7E-5
초). 여기에 칩 피어슨의 같은 문자열 배열 반환 함수의 : 여기
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
이있어 검사 로그 (그의 광산, SplitMultiDelims2 SplitMultiDelims입니다) 메모리 쓰기를 피하기 위해 양 방향으로
> 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
실행이
을 장애아래의 테스트 코드는 Timer
을 사용하므로 지나치게 정확하지는 않지만 그 차이를 보여주기에 충분합니다.
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
몇 가지 다른 구분 기호로 분리하려면; 구분 기호를 배열에 나열하고 for 루프로 바꾼 다음 분할합니다.
For Each tSep In Array(";", " ", ".", "<==", ":", vbCr)
val1 = Replace(val1, tSép, "°")
Next tSep
tab1 = Split(val1, "°")
트림 기능을 사용할 수있는 이중 공간을 사용하지 않으려는 경우 – juanora