how to find the number of occurrences of a substri

2019-01-14 18:13发布

问题:

I have a string (for example: "Hello there. My name is John. I work very hard. Hello there!") and I am trying to find the number of occurrences of the string "hello there". So far, this is the code I have:

Dim input as String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase as String = "hello there"
Dim Occurrences As Integer = 0

If input.toLower.Contains(phrase) = True Then
    Occurrences = input.Split(phrase).Length      
    'REM: Do stuff
End If

Unfortunately, what this line of code seems to do is split the string every time it sees the first letter of phrase, in this case, h. So instead of the result Occurrences = 2 that I would hope for, I actually get a much larger number. I know that counting the number of splits in a string is a horrible way to go about doing this, even if I did get the correct answer, so could someone please help me out and provide some assistance?

回答1:

You can create a Do Until loop that stops once an integer variable equals the length of the string you're checking. If the phrase exists, increment your occurences and add the length of the phrase plus the position in which it is found to the cursor variable. If the phrase can not be found, you are done searching (no more results), so set it to the length of the target string. To not count the same occurance more than once, check only from the cursor to the length of the target string in the Loop (strCheckThisString).

    Dim input As String = "hello there. this is a test. hello there hello there!"
    Dim phrase As String = "hello there"
    Dim Occurrences As Integer = 0

    Dim intCursor As Integer = 0
    Do Until intCursor >= input.Length

        Dim strCheckThisString As String = Mid(LCase(input), intCursor + 1, (Len(input) - intCursor))

        Dim intPlaceOfPhrase As Integer = InStr(strCheckThisString, phrase)
        If intPlaceOfPhrase > 0 Then

            Occurrences += 1
            intCursor += (intPlaceOfPhrase + Len(phrase) - 1)

        Else

            intCursor = input.Length

        End If

    Loop


回答2:

the best way to do it is this:

Public Function countString(ByVal inputString As String, ByVal stringToBeSearchedInsideTheInputString as String) As Integer
    Return System.Text.RegularExpressions.Regex.Split(inputString, stringToBeSearchedInsideTheInputString).Length -1

End Function


回答3:

Yet another idea:

Dim input As String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase As String = "Hello there"
Dim Occurrences As Integer = (input.Length - input.Replace(phrase, String.Empty).Length) / phrase.Length

You just need to make sure that phrase.Length > 0.



回答4:

str="Thisissumlivinginsumgjhvgsum in the sum bcoz sum ot ih sum"
b= LCase(str)
array1=Split(b,"sum")
l=Ubound(array1)
msgbox l

the output gives u the no. of occurences of a string within another one.



回答5:

You just have to change the input of the split function into a string array and then delare the StringSplitOptions.

Try out this line of code:

Occurrences = input.Split({phrase}, StringSplitOptions.None).Length

I haven't checked this, but I'm thinking you'll also have to account for the fact that occurrences would be too high due to the fact that you're splitting using your string and not actually counting how many times it is in the string, so I think Occurrences = Occurrences - 1

Hope this helps



回答6:

You could create a recursive function using IndexOf. Passing the string to be searched and the string to locate, each recursion increments a Counter and sets the StartIndex to +1 the last found index, until the search string is no longer found. Function will require optional parameters Starting Position and Counter passed by reference:

Function InStrCount(ByVal SourceString As String, _
                    ByVal SearchString As String, _
                    Optional ByRef StartPos As Integer = 0, _
                    Optional ByRef Count As Integer = 0) As Integer
    If SourceString.IndexOf(SearchString, StartPos) > -1 Then
        Count += 1
        InStrCount(SourceString, _
                   SearchString, _
                   SourceString.IndexOf(SearchString, StartPos) + 1, _
                   Count)
    End If
    Return Count
End Function

Call function by passing string to search and string to locate and, optionally, start position:

Dim input As String = "Hello there. My name is John. I work very hard. Hello there!"
Dim phrase As String = "hello there"
Dim Occurrences As Integer

Occurrances = InStrCount(input.ToLower, phrase.ToLower)

Note the use of .ToLower, which is used to ignore case in your comparison. Do not include this directive if you do wish comparison to be case specific.



回答7:

One more solution based on InStr(i, str, substr) function (searching substr in str starting from i position, more info about InStr()):

Function findOccurancesCount(baseString, subString)
    occurancesCount = 0
    i = 1
    Do
        foundPosition = InStr(i, baseString, subString) 'searching from i position
        If foundPosition > 0 Then                       'substring is found at foundPosition index
            occurancesCount = occurancesCount + 1       'count this occurance
            i = foundPosition + 1                       'searching from i+1 on the next cycle
        End If
    Loop While foundPosition <> 0
    findOccurancesCount = occurancesCount
End Function

As soon as there is no substring found (InStr returns 0, instead of found substring position in base string), searching is over and occurances count is returned.



回答8:

Looking at your original attempt, I have found that this should do the trick as "Split" creates an array. Occurrences = input.split(phrase).ubound

This is CaSe sensitive, so in your case the phrase should equal "Hello there", as there is no "hello there" in the input



回答9:

Expanding on Sumit Kumar's simple solution (please upvote his answer rather than this one), here it is as a one-line working function:

Public Function fnStrCnt(ByVal str As String, ByVal substr As String) As Integer
    fnStrCnt = UBound(Split(LCase(str), substr))
End Function

Demo:

Sub testit()
    Dim thePhrase
    thePhrase = "Once upon a midnight dreary while a man was in a house in the usa."
    If fnStrCnt(thePhrase, " a ") > 1 Then
        MsgBox "Found " & fnStrCnt(thePhrase, " a ") & " occurrences."
    End If
End Sub 'testit()


回答10:

I don't know if this is more obvious? Starting from the beginning of longString check the next characters up to the number characters in phrase, if phrase is not found start looking from the second character etc. If it is found start agin from the current position plus the number of characters in phrase and increment the value of occurences

 Module Module1
Sub Main()

    Dim longString As String = "Hello there. My name is John. I work very hard. Hello there! Hello therehello there"

    Dim phrase As String = "hello There"


    Dim occurences As Integer = 0
    Dim n As Integer = 0

    Do Until n >= longString.Length - (phrase.Length - 1)
        If longString.ToLower.Substring(n, phrase.Length).Contains(phrase.ToLower) Then
            occurences += 1
            n = n + (phrase.Length - 1)
        End If
        n += 1
    Loop
    Console.WriteLine(occurences)


End Sub
End Module


回答11:

I used this in Vbscript, You can convert the same to VB.net as well

Dim str, strToFind
str = "sdfsdf:sdsdgs::"
strToFind = ":"

MsgBox GetNoOfOccurranceOf( strToFind, str)

Function GetNoOfOccurranceOf(ByVal subStringToFind As String, ByVal strReference As String)
    Dim iTotalLength, newString, iTotalOccCount
    iTotalLength = Len(strReference)
    newString = Replace(strReference, subStringToFind, "")
    iTotalOccCount = iTotalLength - Len(newString)
    GetNoOfOccurranceOf = iTotalOccCount
End Function


回答12:

I know this thread is really old, but I got another solution too:

Function countOccurencesOf(needle As String, s As String)
    Dim count As Integer = 0
    For i As Integer = 0 to s.Length - 1
        If s.Substring(i).Startswith(needle) Then
            count = count + 1
        End If
    Next
    Return count
End Function