Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 突出显示算法-匹配长度不等于搜索字符串长度时_Vb.net - Fatal编程技术网

Vb.net 突出显示算法-匹配长度不等于搜索字符串长度时

Vb.net 突出显示算法-匹配长度不等于搜索字符串长度时,vb.net,Vb.net,我有一个突出显示算法,它接受一个字符串,并在其中的匹配项周围添加突出显示代码。我遇到的问题是像“Find tæst”这样的词作为要搜索的字符串,“taest”作为要查找的字符串。因为搜索字符串的长度与匹配的长度不匹配,所以我无法准确地找到匹配的结尾。在我的例子中,IndexOf向我展示了比赛,但由于组合的æ被算作一个字符,它使我无法检测到比赛的结束。我认为IndexOf在这里对我不起作用。返回匹配的索引和匹配的长度的东西将起作用。但我不知道还能用什么 ' cycle through se

我有一个突出显示算法,它接受一个字符串,并在其中的匹配项周围添加突出显示代码。我遇到的问题是像“Find tæst”这样的词作为要搜索的字符串,“taest”作为要查找的字符串。因为搜索字符串的长度与匹配的长度不匹配,所以我无法准确地找到匹配的结尾。在我的例子中,IndexOf向我展示了比赛,但由于组合的æ被算作一个字符,它使我无法检测到比赛的结束。我认为IndexOf在这里对我不起作用。返回匹配的索引和匹配的长度的东西将起作用。但我不知道还能用什么

    ' cycle through search words and replace them in the text
    For intWord = LBound(m_arrSearchWords) To UBound(m_arrSearchWords)

       If m_arrSearchWords(intWord).Length > 0 Then

          ' replace instances of the word with the word surrounded by bold codes

          ' find starting position
          intPos = strText.IndexOf(m_arrSearchWords(intWord), System.StringComparison.CurrentCultureIgnoreCase)
          Do While intPos <> -1

             strText = strText.Substring(0, (intPos - 1) - 0 + 1) & cstrHighlightCodeOn & strText.Substring(intPos, m_arrSearchWords(intWord).Length) & cstrHighlightCodeOff & strText.Substring(intPos + m_arrSearchWords(intWord).Length)
             intPos = strText.IndexOf(m_arrSearchWords(intWord), intPos + m_arrSearchWords(intWord).Length + cstrHighlightCodeOn.Length + cstrHighlightCodeOff.Length, System.StringComparison.CurrentCultureIgnoreCase)

          Loop

       End If

    Next intWord
”在搜索词中循环,并在文本中替换它们
对于intWord=LBound(m_arresearchwords)到UBound(m_arresearchwords)
如果m_arresearchWords(intWord).Length>0,则
'将单词的实例替换为用粗体代码包围的单词
'找到起始位置
intPos=strText.IndexOf(m_arresearchwords(intWord),System.StringComparison.CurrentCultureIgnoreCase)
在intPos-1时执行此操作
strText=strText.Substring(0,(intPos-1)-0+1)和cstrHighlightCodeOn&strText.Substring(intPos,m_arrSearchWords(intWord).Length)和cstrHighlightCodeOff&strText.Substring(intPos+m_arrSearchWords(intWord).Length)
intPos=strText.IndexOf(m_arresearchwords(intWord),intPos+m_arresearchwords(intWord)。Length+cstrHighlightCodeOn.Length+cstrHighlightCodeOff.Length,System.StringComparison.CurrentCultureIgnorase)
环
如果结束
下一个关键词

子字符串方法失败,因为长度超过字符串的结尾。我对以搜索词结尾的字符串(上面未显示)进行了修复。但是较长的字符串将被错误地突出显示,我需要修复这些字符串。

如果我理解正确,您正在寻找一个返回“匹配字符串”的函数-换句话说,当您在
s2
中查找
s1
时,您需要确切地知道
s2
的哪个部分是匹配的(匹配的第一个和最后一个字符的索引)。这允许您突出显示匹配项,并且不会修改字符串(大写/小写、连字等)

我没有VB.net,不幸的是VBA没有与VB.net完全相同的搜索功能-因此请理解以下代码正确地标识了匹配的开始和结束,但它仅使用大写/小写匹配进行测试。我希望这能帮助您解决问题

Option Compare Text
Option Explicit

Function startEndIndex(bigString, smallString)
' function that returns start, end index
' of the match
' it keeps shortening the bigString until no match is found
' this is how it takes care of mismatches in number of characters
' because of a match between "similar" strings
Dim i1, i2
Dim shorterString

i2 = 0

' first see if there is a match at all:
i1 = InStr(1, bigString, smallString, vbTextCompare)

If i1 > 0 Then
  ' largest value that i2 can have is end of string:
  i2 = Len(bigString)

  ' can make it shorter - but no shorter than twice the length of the search string
  If i2 > i1 + 2 * Len(smallString) Then i2 = i1 + 2 * Len(smallString)
  shorterString = Mid(bigString, i1, i2 - i1)

  ' keep making the string shorter until there is no match:
  While InStr(1, shorterString, smallString, vbTextCompare) > 0
    i2 = i2 - 1
    shorterString = Mid(bigString, i1, i2 - i1)
  Wend

End If

' return the values as an array:
startEndIndex = Array(i1, endOfString)

End Function


Sub test()
' a simple test routine to see that things work:
Dim a
Dim longString: longString = "This is a very long TaesT of a complicated string"
a = startEndIndex(longString, "very long taest")
If a(0) = 0 And a(1) = 0 Then
MsgBox "no match found"
Else
Dim highlightString As String
highlightString = Left(longString, a(0) - 1) & "*" & Mid(longString, a(0), a(1) - a(0) + 1) & _
  "*" & Mid(longString, a(1) + 1)
  MsgBox "start at " & a(0) & " and end at " & a(1) & vbCrLf & _
  "string matched is '" & Mid(longString, a(0), a(1) - a(0) + 1) & "'" & vbCrLf & _
  "with highlighting: " & highlightString
End If
End Sub

虽然IndexOf返回匹配长度会很好,但事实证明,您可以自己进行比较以找出匹配长度。我只需对长度进行二次比较,以找到最大的匹配。我从搜索的单词的长度开始,该长度应该是最大的。然后我会反向查找长度。一旦我找到了我使用的长度。如果我找不到,我会增加长度。如果我搜索的字符串更大或更小,这会起作用。这意味着在正常情况下,至少会进行一次额外的比较,在最坏的情况下,会根据搜索词的长度增加一个数字。也许如果我有IndexOf的实现,我会我们应该改进它,但至少这是有效的

    ' cycle through search words and replace them in the text
    For intWord = LBound(m_arrSearchWords) To UBound(m_arrSearchWords)

       If m_arrSearchWords(intWord).Length > 0 Then

          ' find starting position
          intPos = strText.IndexOf(m_arrSearchWords(intWord), System.StringComparison.CurrentCultureIgnoreCase)
          Do While intPos <> -1

             intOrigLength = m_arrSearchWords(intWord).Length

             ' if there isn't enough of the text left to add the search word length to
             If strText.Length < ((intPos + intOrigLength - 1) - 0 + 1) Then

                ' use shorter length
                intOrigLength = ((strText.Length - 1) - intPos + 1)

             End If

             ' find largest match
             For intLength = intOrigLength To 1 Step -1

                If m_arrSearchWords(intWord).Equals(strText.Substring(intPos, intLength), StringComparison.CurrentCultureIgnoreCase) Then

                   ' if match found, highlight it
                   strText = strText.Substring(0, (intPos - 1) - 0 + 1) & cstrHighlightCodeOn & strText.Substring(intPos, intLength) & cstrHighlightCodeOff & strText.Substring(intPos + intLength)

                   ' find next
                   intPos = strText.IndexOf(m_arrSearchWords(intWord), intPos + intLength + cstrHighlightCodeOn.Length + cstrHighlightCodeOff.Length, System.StringComparison.CurrentCultureIgnoreCase)

                   ' exit search for largest match
                   Exit For

                End If

             Next

             ' if we didn't find it by searching smaller - search larger
             If intLength = 0 Then

                For intLength = intOrigLength + 1 To ((strText.Length - 1) - intPos + 1)

                   If m_arrSearchWords(intWord).Equals(strText.Substring(intPos, intLength), StringComparison.CurrentCultureIgnoreCase) Then

                      ' if match found, highlight it
                      strText = strText.Substring(0, (intPos - 1) - 0 + 1) & cstrHighlightCodeOn & strText.Substring(intPos, intLength) & cstrHighlightCodeOff & strText.Substring(intPos + intLength)

                      ' find next
                      intPos = strText.IndexOf(m_arrSearchWords(intWord), intPos + intLength + cstrHighlightCodeOn.Length + cstrHighlightCodeOff.Length, System.StringComparison.CurrentCultureIgnoreCase)

                      ' exit search for largest match
                      Exit For

                   End If

                Next

             End If

          Loop

       End If

    Next intWord
”在搜索词中循环,并在文本中替换它们
对于intWord=LBound(m_arresearchwords)到UBound(m_arresearchwords)
如果m_arresearchWords(intWord).Length>0,则
'找到起始位置
intPos=strText.IndexOf(m_arresearchwords(intWord),System.StringComparison.CurrentCultureIgnoreCase)
在intPos-1时执行此操作
intOrigLength=m_arrSearchWords(intWord).Length
'如果没有足够的文本来添加搜索词长度
如果strText.Length<((intPos+intOrigLength-1)-0+1),则
“使用较短的长度
intOrigLength=((strText.Length-1)-intPos+1)
如果结束
“找到最大匹配项
对于intLength=intOrigLength到1步骤-1
如果m_arresearchwords(intWord).Equals(strText.Substring(intPos,intLength),StringComparison.CurrentCultureIgnoreCase),则
'如果找到匹配项,请突出显示它
strText=strText.Substring(0,(intPos-1)-0+1)&cstrHighlightCodeOn&strText.Substring(intPos,intLength)&cstrHighlightCodeOff&strText.Substring(intPos+intLength)
“找到下一个
intPos=strText.IndexOf(m_arresearchwords(intWord),intPos+intLength+cstrHighlightCodeOn.Length+cstrHighlightCodeOff.Length,System.StringComparison.CurrentCultureIgnoreCase)
'退出搜索最大匹配项
退出
如果结束
下一个
“如果我们没有通过搜索较小的搜索找到它,请搜索较大的搜索
如果intLength=0,则
对于intLength=intOrigLength+1到((strText.Length-1)-intPos+1)
如果m_arresearchwords(intWord).Equals(strText.Substring(intPos,intLength),StringComparison.CurrentCultureIgnoreCase),则
'如果找到匹配项,请突出显示它
strText=strText.Substring(0,(intPos-1)-0+1)&cstrHighlightCodeOn&strText.Substring(intPos,intLength)&cstrHighlightCodeOff&strText.Substring(intPos+intLength)
“找到下一个
intPos=strText.IndexOf(m_arresearchwords(intWord),intPos+intLength+cstrHighlightCodeOn.Length+cstrHighlightCodeOff.Length,System.StringComparison.CurrentCultureIgnoreCase)
'退出搜索最大匹配项
退出
如果结束
下一个
如果结束
环
如果结束
下一个关键词
这是一个错误