【问题标题】:Search for 2nd occurrence of a string in VBA在 VBA 中搜索第二次出现的字符串
【发布时间】:2020-07-03 04:51:48
【问题描述】:

如何在 VBA 中搜索另一个字符串中第二次出现的字符串?

例如,在下面给定的字符串中,单词“test”出现了两次。

这是一个测试测试

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    只需搜索两次

    Sub Demo()
        Dim DataString As String
        Dim SearchString As String
        Dim i As Long
    
        DataString = "this is a test to test"
        SearchString = "test"
    
        i = InStr(1, DataString, SearchString, vbTextCompare)
        i = InStr(i + 1, DataString, SearchString, vbTextCompare)
    
        Debug.Print "Second occurance starts at position " & i
    End Sub
    

    【讨论】:

      【解决方案2】:

      更新
      要找到最后一次出现,那么只需

      MsgBox InStrRev("this is a test to test", "test")
      

      处理少于​​ 2 次的初始答案

      有点笨拙,但处理 1 或 0 次出现

      Dim strIn As String
      Dim strOut As String
      Dim lngPos As Long
      Dim lngPos2 As Long
      
      strIn = "test"
      strOut = "this is a test to test"
      
      lngPos = InStr(strOut, strIn)
      
      If lngPos > 0 Then
          lngPos2 = InStr(lngPos + 1, strOut, strIn)
          If lngPos2 > 0 Then MsgBox strIn & " at " & lngPos2
      Else
          MsgBox "No " & strIn
      End If
      

      【讨论】:

        【解决方案3】:

        要查找第二次出现的字符串,请使用 InStr 函数两次。请注意,您搜索的子字符串可能是重复的字符序列,例如“dd”。在这种情况下,您必须确定是否要返回 5 或 6 作为在“abcdddd”中搜索“bb”的结果。也就是说,您是要在第一次出现的末尾还是在第一次出现的第二个字符处开始搜索“dd”的第二次出现?

        Private Sub ExampleFind2ndOccurrence()
            Dim intFirst As Integer, intSecond As Integer
            Dim searchThisString As String: searchThisString = "abcdddddefg"
            Dim forThisSubString As String: forThisSubString = "dd"
        
            ' Find the first occurrence of forThisSubString
            intFirst = InStr(1, searchThisString, forThisSubString, vbTextCompare)
        
            ' Find the second occurrence of forThisSubString
            intSecond = InStr(1, Mid(searchThisString, intFirst + 1), forThisSubString, vbTextCompare)
            If intSecond > 0 Then intSecond = intFirst + intSecond
            Debug.Print "2nd occurrence occurs at character position "; intSecond
        
            ' Alternate method to find second occurrence of forThisSubString in the
            ' case where there can be no overlap
            intSecond = InStr(1, Mid(searchThisString, intFirst + Len(forThisSubString)), forThisSubString, vbTextCompare)
            If intSecond > 0 Then intSecond = intFirst + Len(forThisSubString) - 1 + intSecond
            Debug.Print "Prohibbitting overlap, 2nd occurrence occurs at character position "; intSecond
        End Sub
        

        查找第 N 次出现的子字符串:

        Public Function InStr2(ByVal IntStartPosition As Variant _
                               , ByVal Str As String _
                               , ByVal SubStr As String _
                               , Optional IntCompareMethod As Integer = vbTextCompare _
                               , Optional IntOccurrence As Integer = 1 _
                               , Optional BlnOverlapOK As Boolean = False)
        ' Find the IntOccurrence instance of SubStr in Str
        ' Parameters:
            ' IntStartPosition (Integer): the character position at which to start searching.
                                         ' (See docs for InStr)
            ' Str (String): the string to search.  (See docs for InStr)
            ' SubStr (String): the substring to find in Str.  (See docs for InStr)
            ' IntCompareMethod (integer): a VBA compare enumeration value.  (See docs for InStr)
            ' IntOccurrence (integer): The number of instances of SubStr for which to search
            ' BlnOverlapOK (boolean): Is it okay for the Nth occurence of SubStr to overlap the
                                      ' N-1 occurrence?
        ' Returns the location of the occurence of the IntOccurrence instance of SubStr in Str
            Dim s As String
            Dim intCharPos As Integer
            Dim cnt As Integer
            Dim intStart As Integer
            Dim i As Integer
        
            ' Initialize
            If IsMissing(IntStartPosition) Then IntStartPosition = 1
            intStart = IntStartPosition
            Str = Mid(Str, intStart)
        
            intCharPos = 1
            cnt = 0
            i = 1
            Do While intCharPos <= Len(Str) And cnt < IntOccurrence
                s = Mid(Str, intCharPos)
                i = InStr(1, s, SubStr, IntCompareMethod)
                If i = 0 Or i = Null Then
                    InStr2 = i
                    Exit Function
                End If
                cnt = cnt + 1
                If BlnOverlapOK Or Len(SubStr) = 1 Or cnt = IntOccurrence Then
                    intCharPos = intCharPos + i
                Else
                    intCharPos = intCharPos + i + Len(SubStr) - 1
                End If
            Loop
            InStr2 = intCharPos - 1
        
        End Function
        

        查找第 n 次出现的子字符串的示例:

        Private Sub InStr2Example()
            Dim i As Integer
            Dim searchThisString As String: searchThisString = "abcddddddd"
                                                               '1234567890
            Dim forThisSubString As String: forThisSubString = "dd"
            i = InStr2(1, searchThisString, forThisSubString, vbTextCompare, 3, True)
            Debug.Print "3rd occurrence occurs at character position "; i
            i = InStr2(1, searchThisString, forThisSubString, vbTextCompare, 3, False)
            Debug.Print "Prohibbitting overlap, 3rd occurrence occurs at character position "; i
        End Sub
        

        【讨论】:

          【解决方案4】:

          您需要找到第一次出现的开始位置,然后相应地偏移搜索范围。

          嵌套的Mid/InStr 函数可以解决问题:

          Dim x As String, fVal As String
          
          x = "test this is a test"
          fVal = "test"
          
          y = Mid$(Mid$(x, InStr(x, fVal) + Len(fVal)), InStr(Mid$(x, InStr(x, fVal) + Len(fVal)), fVal))
          
          Debug.Print y
          

          【讨论】:

            【解决方案5】:

            使用Split() 查找任何 事件的灵活函数可能是:

            Function GetPosition(ByVal FullText As String, ByVal SearchString As String, ByVal occurrence As Long, Optional ByVal CaseSensitive As Boolean = False) As Long
            'Purpose: get start position of a given search occurrence within fulltext
            '[0]case sensitive? (case insensitive by default)
                If Not CaseSensitive Then
                    FullText = LCase(FullText): SearchString = LCase(SearchString)
                End If
            '[1]split fulltext into substrings
                Dim part: part = Split(FullText, SearchString)  ' split fulltext
                If occurrence < 1 Then Exit Function            ' accept only positive occurrencies
                If occurrence > UBound(part) Then Exit Function ' refuse too high occurrencies
            '[2]add substrings plus searchstring lengths
                Dim i As Long, n As Long                        ' counters
                For i = 0 To occurrence - 1
                    n = n + Len(part(i))                        ' add part lengths
                Next
                n = n + (occurrence - 1) * Len(SearchString) + 1
            '[3]return search position of wanted occurrence
                GetPosition = n
            End Function
            

            调用示例

            Sub Test()
            Dim s As String: s = "this is a test to test to test"  ' (three occurrencies of "test")
            Dim i As Long
            For i = 1 To 4
                Debug.Print "Occurrence " & i, "starts at position " & GetPosition(s, "tEst", i)
            Next
            End Sub
            
            

            【讨论】:

              猜你喜欢
              • 2017-01-21
              • 2014-07-08
              • 2018-02-05
              • 2017-11-02
              • 2013-05-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多