如何在字符串vb.net中查找子字符串的出现次数

Posted

技术标签:

【中文标题】如何在字符串vb.net中查找子字符串的出现次数【英文标题】:how to find the number of occurrences of a substring within a string vb.net 【发布时间】:2012-12-26 12:39:43 【问题描述】:

我有一个字符串(例如:"Hello there. My name is John. I work very hard. Hello there!"),我正在尝试查找字符串"hello there" 的出现次数。到目前为止,这是我拥有的代码:

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

不幸的是,这行代码似乎是在每次看到phrase 的第一个字母(在本例中为h)时拆分字符串。因此,我实际上得到的不是我希望的结果Occurrences = 2,而是更大的数字。我知道计算字符串中的分割数是一种可怕的方法,即使我确实得到了正确的答案,所以有人可以帮助我并提供一些帮助吗?

【问题讨论】:

问题的格式不正确。如果你使用 vb.net 的标签,那么 Split 函数将接受一个字符串,而不仅仅是一个字符。所以在你的情况下,它会是 3,因为你忘了减去 1。参考:msdn.microsoft.com/en-us/library/… 【参考方案1】:

在Sumit Kumar's simple solution上扩展,这里是一个单行工作函数:

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

演示:

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()

【讨论】:

【参考方案2】:

基于InStr(i, str, substr)函数的另一种解决方案(从i位置开始在str中搜索substr,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

一旦没有找到子字符串(InStr 返回0,而不是在基本字符串中找到子字符串位置),搜索结束并返回出现次数。

【讨论】:

【参考方案3】:

最好的方法是:

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

【讨论】:

如何处理重叠的搜索字符串? Dim inputString = "songs ABBABBA popsongs"' and 'Dim stringToBeSearchedInsideTheInputString = "ABBA" 返回值是多少(1 或 2)? 有趣的观察。我的解决方案 ABBA 的出现次数为 1。如果您需要处理此类异常,则需要不同的方法,但我从不需要它。注意:即使是公认的解决方案也不能满足您的需求。【参考方案4】:
str="Thisissumlivinginsumgjhvgsum in the sum bcoz sum ot ih sum"
b= LCase(str)
array1=Split(b,"sum")
l=Ubound(array1)
msgbox l

输出给你没有。一个字符串在另一个字符串中的出现次数。

【讨论】:

+1 好答案 - 点赞。 Here it is 稍微修改为单行函数。【参考方案5】:

我知道这个帖子很老了,但我也有另一个解决方案:

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

【讨论】:

【参考方案6】:

我在 Vbscript 中使用过,您也可以将其转换为 VB.net

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

【讨论】:

【参考方案7】:

查看您最初的尝试,我发现这应该可以解决问题,因为“拆分”会创建一个数组。 出现次数 = input.split(phrase).ubound

这是对 CaSe 敏感的,因此在您的情况下,该短语应等于“Hello there”,因为输入中没有“hello there”

【讨论】:

【参考方案8】:

您可以使用 IndexOf 创建递归函数。传递要搜索的字符串和要定位的字符串,每次递归都会增加一个 Counter 并将 StartIndex 设置为 +1 最后找到的索引,直到不再找到搜索字符串。函数将需要通过引用传递的可选参数起始位置和计数器:

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

通过将字符串传递给搜索和字符串来定位以及可选的起始位置来调用函数:

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)

注意 .ToLower 的使用,它用于在比较中忽略大小写。如果您确实希望比较具体情况,请不要包含此指令。

【讨论】:

【参考方案9】:

我不知道这是否更明显? 从longString的开头开始检查下一个字符直到phrase中的数字字符,如果没有找到phrase,则从第二个字符开始查找,以此类推。如果找到,则从当前位置加上数字开始phrase 中的字符数并增加 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

【讨论】:

【参考方案10】:

还有一个想法:

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

您只需要确保phrase.Length &gt; 0

【讨论】:

【参考方案11】:

您可以创建一个 Do Until 循环,该循环在整数变量等于您正在检查的字符串的长度时停止。如果短语存在,则增加出现次数并将短语的长度加上找到它的位置添加到游标变量中。如果找不到该短语,则您已完成搜索(没有更多结果),因此请将其设置为目标字符串的长度。为了不多次计算相同的出现,只检查从光标到循环中目标字符串的长度(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

【讨论】:

这看起来不错,但是你能补充一点关于你在这里做什么的解释吗? 谢谢。已编辑说明。 不确定为什么这是“最佳答案” - Neolisk 下面的字符串替换方法更清晰……试试吧!打印 Len("Cat/Dogo/Rabbit") - Len(Replace("Cat/dog/Rabbit", "/", ""))-1 接受的答案并不总是意味着最佳答案。 这是一个任务的大量代码,解决方案更简单。 “字符串/拆分/长度减一”的方法更容易阅读和理解。【参考方案12】:

您只需将 split 函数的输入更改为字符串数组,然后删除StringSplitOptions

试试这行代码:

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

我还没有检查过这个,但我认为你还必须考虑这样一个事实,即出现次数太高,因为你正在使用你的字符串进行拆分而不是实际计算多少次它在字符串中,所以 我认为 Occurrences = Occurrences - 1

希望对你有帮助

【讨论】:

以上是关于如何在字符串vb.net中查找子字符串的出现次数的主要内容,如果未能解决你的问题,请参考以下文章

怎么查找一个string 字符串中的子字符串出现的次数和位置

字符串查找目标子串出现的次数

查找字符串的子串,使得子串的长度与其出现次数的乘积最大化

在字符串 C# 中查找子字符串的计数

在字符串中查找随机顺序子字符串

KMP算法(查找子序列)