programing

문자열에서 슬래시 발생 횟수를 찾는 방법

easyjava 2023. 4. 9. 22:28
반응형

문자열에서 슬래시 발생 횟수를 찾는 방법

Excel VBA 매크로를 사용하여 문자열 내에서 슬래시 문자( / )의 발생 횟수를 확인하려면 어떻게 해야 합니까?

오래된 질문이지만, 엑셀 포럼에서 찾은 답변으로 답변의 질을 높이고 싶다고 생각했습니다.카운트는 다음 방법으로도 확인할 수 있다고 합니다.

    count =Len(string)-Len(Replace(string,"/",""))

답변에 대한 모든 크레딧은 원본 작성자(http://www.ozgrid.com/forum/showthread.php?t=45651)에게 제공됩니다.

다음과 같이 다음 기능을 사용합니다.count = CountChrInString(yourString, "/").

'''
''' Returns the count of the specified character in the specified string.
'''
Public Function CountChrInString(Expression As String, Character As String) As Long
'
' ? CountChrInString("a/b/c", "/")
'  2
' ? CountChrInString("a/b/c", "\")
'  0
' ? CountChrInString("//////", "/")
'  6
' ? CountChrInString(" a / b / c ", "/")
'  2
' ? CountChrInString("a/b/c", " / ")
'  0
'
    Dim iResult As Long
    Dim sParts() As String

    sParts = Split(Expression, Character)

    iResult = UBound(sParts, 1)

    If (iResult = -1) Then
    iResult = 0
    End If

    CountChrInString = iResult

End Function
Function CountOfChar(str as string, character as string) as integer
      CountOfChar = UBound(Split(str, character))
End Function

BTW, 퍼포먼스를 중시하는 경우는, 스플릿 또는 치환을 사용해 카운트를 판별하는 것보다, 이하가 20% 고속입니다.

Private Function GetCountOfChar( _
  ByRef ar_sText As String, _
  ByVal a_sChar As String _
) As Integer
  Dim l_iIndex As Integer
  Dim l_iMax As Integer
  Dim l_iLen As Integer

  GetCountOfChar = 0
  l_iMax = Len(ar_sText)
  l_iLen = Len(a_sChar)
  For l_iIndex = 1 To l_iMax
    If (Mid(ar_sText, l_iIndex, l_iLen) = a_sChar) Then 'found occurrence
      GetCountOfChar = GetCountOfChar + 1
      If (l_iLen > 1) Then l_iIndex = l_iIndex + (l_iLen - 1) 'if matching more than 1 char, need to move more than one char ahead to continue searching
    End If
  Next l_iIndex
End Function

다른 함수를 호출하지 않을 때 사용할 수 있는 단일 회선 버전입니다.이것은 Count Chr In String 및 기타 위의 압축 버전일 뿐입니다.

? UBound(Split("abcabcabc", "cd"), 1)

0이 반환됩니다.cd를 ab로 변경하면 3이 반환됩니다.변수에도 대응합니다.체크되고 있는 문자열(abcabc...)이 비어 있는 경우 -1이 반환됩니다.

Santhosh Divakar의 답변이 마음에 들었기 때문에 검색 문자의 길이로 결과를 나누면 여러 문자를 체크할 수 있는 가능성을 고려하여 확장했습니다.

Function Num_Characters_In_String(Input_String As String, Search_Character As String) As Integer
'Returns the number of times a specified character appears in an input string by replacing them with an empty string
'   and comparing the two string lengths. The final result is then divided by the length of the Search_Character to
'   provide for multiple Search Characters.

    Num_Characters_In_String = (Len(Input_String) - Len(Replace(Input_String, Search_Character, ""))) / Len(Search_Character)

End Function

예를 들어, 의 결과는

Num_Characters_In_String("One/Two/Three/Four//", "//")

는 1을 나타냅니다.왜냐하면 문장 끝에 이중 슬래시만 있기 때문입니다.

퍼포먼스와 메모리 사용을 최소한으로 억제하는 경우는, 스플릿 솔루션과 렌/치환 솔루션이 모두 최적인 것은 아닙니다.

제 제안서입니다.

Public Function CountOf(ByRef s As String, ByRef substr As String, Optional ByVal compareMethod As VbCompareMethod = vbBinaryCompare) As Integer

Dim c As Integer
Dim idx As Integer

NEXT_MATCH:
idx = InStr(idx + 1, s, substr, compareMethod)
If idx > 0 Then
    c = c + 1
    GoTo NEXT_MATCH:
End If

CountOf = c + 1
End Function

퍼포먼스는 다음과 같습니다.단순한 케이스로 각 옵션을 1,000,000회 실행하고 엔트리가 많은 케이스도 1개씩 실행합니다.

5.828ms       Empty Loop
s = '0,1,2,3,4,5,6,7,8,9', separator = ','
1.882s         UBound(Split) algo
2.537s         Len/Replace() algo
760.710ms      CountOf()

s = '[ABC],long, longer,sdfgshttsdbghhgsssssshsdhhhhhhhhhhhh,,,,777777777777777777777777777777,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,LAST', separator = ','
18.330s        UBound(Split) algo
21.743s        Len/Replace() algo
9.544s         CountOf()

따라서 Count Of가 함수 호출인 경우에도 전체적으로 약 2~3배 빨라지고 Split 및 Len/Replace가 루프 코드에 직접 포함되어 있습니다.

또한 아래와 같이 항목 수와 길이가 증가해도 성능비는 안정적입니다(테스트는 1,000회만 반복).

s ="[ABC],long,longer,sdfgshttsdbghhgsssssshsdhhhhhhhhhhhh,,,,777777777777777777777,Repeat(1000,"A...Z"),LAST', separator = ','
232.160ms      UBound(Split): 1033
325.367ms      Len/Replace(): 1033
113.658ms      CountOf(): 1033

앞에서 설명한 바와 같이 퍼포먼스와 메모리 사용률은 문제가 되지 않지만 큰 파일을 하나의 문자열로 읽는 경우에는 문제가 될 수 있습니다.@Alexis_Martial은 이것을 시도했지만 a) 불필요한 것을 가지고 있었다.goto스테이트먼트 b) 검색되는 문자열의 길이를 고려하지 않습니다.

Public Function Occurences(ByRef s As String, ByRef substr As String, Optional ByVal compareMethod As VbCompareMethod = vbBinaryCompare) As Long
Dim idx As Long
Dim sublen As Long
    sublen = Len(substr)
    idx = 1
    Occurences = -1
    Do
        Occurences = Occurences + 1
        idx = InStr(idx, s, substr, compareMethod) + sublen
    Loop While idx > sublen
End Function

이것은 VBA Excel 매크로용 간단한 솔루션입니다.

Function CharCount(str As String, chr As String) As Integer
     CharCount = Len(str) - Len(Replace(str, chr, ""))
End Function

또 다른 좋은 방법은 RegExp를 사용하는 것입니다.Microsoft Word에서 다음을 시도했지만, Excel에서도 거의 동일하게 동작한다고 확신합니다.

190,000개의 단어와 2,400개의 세 글자의 인스턴스가 포함된 Word 문서에서 다음 함수는 그것들을 세는 데 평균 0.938초가 걸렸습니다(시간을 편리하게 표시하기 위해 그 아래에 Sub를 포함합니다).

Function RegExpCount(WholeString As String, Substring As String) As Long

Dim MatchCol As MatchCollection

With New RegExp
    .Pattern = Substring
    .Global = True
    .IgnoreCase = False 'or True, depending on your needs
    .MultiLine = False
    Set MatchCol = .Execute(WholeString)
End With

RegExpCount = MatchCol.count

End Function

Sub CountInstances()
Dim StartTime As Double
Dim SecondsElapsed As Double
'Remember time when macro starts
  StartTime = Timer

Dim Rng As Range
Set Rng = ActiveDocument.Range
Debug.Print "The number of times 'your substring' appears in this document is: " & RegExpCount(Rng.Text, "your substring")

'Calculate how many seconds code took to run
  SecondsElapsed = Round(Timer - StartTime, 2)

'Notify user in seconds
  MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation

End Sub

2400은 항상 올바르게 출력됩니다.Alexis Martial의 Count Of 함수는 Rick_R의 UBound(Split) 명령어와 같은 시간이 소요되었습니다.모두 약 0.92~0.95초 만에 동일한 카운트를 출력합니다.

언급URL : https://stackoverflow.com/questions/9260982/how-to-find-number-of-occurences-of-slash-from-a-strings

반응형