我目前有一个搜索工作,并通过将找到的文本替换为找到的文本来突出显示找到的文本,但是用span标记包装以突出显示。除两个问题外,工作正常。它目前区分大小写,我无法弄清楚如何滚动到第一个找到的实例。如果用户搜索“喷嘴”,他们需要能够找到“喷嘴”。这是我的代码。
Try
tmrSearch.Stop()
Try
If txtSearch.Text.Length <= 3 Then
If txtSearch.Text <> "" Then
MessageBox.Show("Please enter longer search terms!")
txtSearch.Text = String.Empty
End If
Else
Dim searchString As String = txtSearch.Text
Dim textToSearch As String = wbContent.Document.Body.InnerHtml
textToSearch = textToSearch.Replace(searchString, "<span style=""background-color:yellow"">" & searchString & "</span>")
If textToSearch.IndexOf(searchString) <> -1 Then
wbContent.Document.Body.InnerHtml = textToSearch
Else
MessageBox.Show(searchString & " is not located in this text!")
End If
txtSearch.Text = String.Empty
End If
Catch ex As Exception
MessageBox.Show("Please enter search terms!")
logger.WriteLog("Error Message : " & ex.Message)
End Try
Catch ex As Exception
logger.WriteLog("frmContent : tmrSearch_Tick() : FAILED")
logger.WriteLog("Error Message : " & ex.Message)
End Try
我知道.Replace()
区分大小写,所以我想我会强制降低textToSearch
但是当我把它放回去时,Web浏览器控件中的所有文本都是小写的。这不符合我的需要。这里的任何建议将不胜感激。
答案 0 :(得分:1)
基本上,您可以尝试拆分小写innertext以查找搜索字符串的存在位置。然后使用拆分中的字符串长度从原始案例副本重建innerText。您需要导入system.text才能使用stringbuilder。
Else
Dim searchString As String = txtSearch.Text
Dim textOriginal As String = wbContent.Document.Body.InnerHtml
Dim textToLower As String = wbContent.Document.Body.InnerHtml.ToLower()
Dim textPieces() as String = textToLower.Split(New String() {searchString}, StringSplitOptions.RemoveEmptyEntries)
Dim i as integer = 0
Dim strNewInnerHtml as New StringBuilder
For each strPiece as String In textPieces
strNewInnerHtml.append(textOriginal.Substring(i,strPiece.Length)
strNewInnerHtml.append("<span style=""background-color:yellow"">" & searchString & "</span>")
i += strPiece.Length + searchString.Length
Next
If textToLower.IndexOf(searchString) <> -1 Then
wbContent.Document.Body.InnerHtml = strNewInnerHtml.ToString()
Else
MessageBox.Show(searchString & " is not located in this text!")
End If
txtSearch.Text = String.Empty
End If
答案 1 :(得分:1)
您可以使用string.Replace(...)扩展方法,以下是一个示例C#代码(VB代码版本在此帖子的P.S.中):
using System;
using System.Text;
namespace StringClassExtensions
{
public static class StringReplaceExtension
{
public static string Replace(this string str,
string oldValue, string newValue,
StringComparison comparisonType)
{
const int maxCapacity = 16777215;
if (string.IsNullOrEmpty(str)) return str;
if (string.IsNullOrEmpty(newValue)) return str;
if (oldValue == null) throw new ArgumentNullException("oldValue");
if (oldValue.Length == 0) return str;
if (str.Length > maxCapacity) throw new ArgumentException("'str' is too long");
if (oldValue.Length > maxCapacity) throw new ArgumentException("'oldValue' is too long");
if (newValue.Length > maxCapacity) throw new ArgumentException("'newValue' is too long");
int currentSearchPosition, lastSearchStartPosition = 0;
var returnValue = new StringBuilder(str.Length, maxCapacity);
while ((currentSearchPosition = str.IndexOf(oldValue, lastSearchStartPosition, comparisonType)) >= 0)
{
if (currentSearchPosition >= lastSearchStartPosition)
returnValue.Append(str.Substring(lastSearchStartPosition, currentSearchPosition - lastSearchStartPosition) + newValue);
lastSearchStartPosition = currentSearchPosition + oldValue.Length;
}
if (lastSearchStartPosition == 0) return str;
if (lastSearchStartPosition < str.Length)
returnValue.Append(str.Substring(lastSearchStartPosition));
return returnValue.ToString();
}
}
}
并只编辑原始代码的一行:
textToSearch = textToSearch.Replace(searchString, "<span style=""background-color:yellow"">" & searchString & "</span>")
到
textToSearch = textToSearch.Replace(searchString,
"<span style=""background-color:yellow"">" & searchString + "</span>",
StringComparison.InvariantCultureIgnoreCase)
注意:原始string.Replace(...)方法的代码发布在referencesource.microsoft.com和AFAIS上它使用有效的内部实现 - 只有当原始方法不是时,才使用此处发布的扩展方法&#t; t合适的。
P.S。这是我的示例String.Replace(...)方法的VB版本。我在developerFusion上通过自动转换获得了VB版本,然后我手动编辑了转换结果VB代码并进行了简单测试。它似乎运作良好。
Imports System.Text
Namespace StringClassExtensions
Public Module StringReplaceExtension
<System.Runtime.CompilerServices.Extension> _
Public Function Replace(str As String, oldValue As String, newValue As String, comparisonType As StringComparison) As String
Const maxCapacity As Integer = 16777215
If String.IsNullOrEmpty(str) Then
Return str
End If
If String.IsNullOrEmpty(newValue) Then
Return str
End If
If oldValue Is Nothing Then
Throw New ArgumentNullException("oldValue")
End If
If oldValue.Length = 0 Then
Return str
End If
If str.Length > maxCapacity Then
Throw New ArgumentException("'str' is too long")
End If
If oldValue.Length > maxCapacity Then
Throw New ArgumentException("'oldValue' is too long")
End If
If newValue.Length > maxCapacity Then
Throw New ArgumentException("'newValue' is too long")
End If
Dim currentSearchPosition As Integer, lastSearchStartPosition As Integer = 0
Dim returnValue = New StringBuilder(str.Length, maxCapacity)
While (InlineAssignHelper(currentSearchPosition, str.IndexOf(oldValue, lastSearchStartPosition, comparisonType))) >= 0
If currentSearchPosition >= lastSearchStartPosition Then
returnValue.Append(str.Substring(lastSearchStartPosition, currentSearchPosition - lastSearchStartPosition) & newValue)
End If
lastSearchStartPosition = currentSearchPosition + oldValue.Length
End While
If lastSearchStartPosition = 0 Then
Return str
End If
If lastSearchStartPosition < str.Length Then
returnValue.Append(str.Substring(lastSearchStartPosition))
End If
Return returnValue.ToString()
End Function
Private Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
target = value
Return value
End Function
End Module
End Namespace
P.P.S。 string.Replace(...)方法扩展的测试套件
using System;
using System.Text;
using NUnit.Framework;
using StringClassExtensions;
namespace Unit_Tests_CS_ConsoleApplication1
{
[TestFixture]
public class Test_0001_StringReplaceMethodExtensionTests
{
[SetUp]
public void TestSetup()
{ }
[TearDown]
public void TestTearDown()
{ }
[Test]
public void TestNullSourceString()
{
string testStr = null;
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsNull(resultStr);
}
[Test]
public void TestEmptySourceString()
{
string testStr = string.Empty;
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsEmpty(resultStr);
}
[Test]
public void TestNullNewValue()
{
string testStr = "Hello, World!";
string resultStr = testStr.Replace("oldValue", null, StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == testStr);
}
[Test]
public void TestEmptyNewValue()
{
string testStr = "Hello, World!";
string resultStr = testStr.Replace("oldValue", string.Empty, StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == testStr);
}
[Test]
public void TestNullOldValue()
{
Assert.Throws(typeof(ArgumentNullException),
() =>
{
string testStr = "Hello, World!";
string resultStr = testStr.Replace(null, "newValue", StringComparison.InvariantCultureIgnoreCase);
}
);
}
[Test]
public void TestEmptyOldValue()
{
string testStr = "Hello, World!";
string resultStr = testStr.Replace(string.Empty, "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == testStr);
}
[Test]
public void TestOldValueIsMissingInTheSearchStr()
{
string testStr = "Hello, World!";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == testStr);
}
[Test]
public void TestSearchStrEqualsToOldValue()
{
string testStr = "oldValue";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == "newValue");
}
[Test]
public void TestSearchStrStartsWithOldValue()
{
string testStr = "oldValue + some words";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == "newValue + some words");
}
[Test]
public void TestSearchStrEndsWithOldValue()
{
string testStr = "some words + oldValue";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == "some words + newValue");
}
[Test]
public void TestSearchStrHasSeveralOccurrencesOfOldValueSeparatedByOtherChars()
{
string testStr = "some words + oldValue + some more words + oldValue + even more words";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == "some words + newValue + some more words + newValue + even more words");
}
[Test]
public void TestSearchStrHasSeveralOccurrencesOfOldValueFollowingOneAfterAnother()
{
string testStr = "some words + oldValueoldValueoldValue + even more words";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == "some words + newValuenewValuenewValue + even more words");
}
[Test]
public void TestCaseInsensitiveStringComparison()
{
string testStr = "some words + oldValue + OldValue + oldValue + even more words";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
Assert.IsTrue(resultStr == "some words + newValue + newValue + newValue + even more words");
}
[Test]
public void TestCaseSensitiveStringComparison()
{
string testStr = "some words + oldValue + OldValue + oldValue + even more words";
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCulture);
Assert.IsTrue(resultStr == "some words + newValue + OldValue + newValue + even more words");
}
[Test]
public void TestSourceStringIsOutOfMaxCapacity()
{
Assert.Throws(typeof(ArgumentException),
() =>
{
int testCapacity = new StringBuilder().MaxCapacity / 128 + 1;
string testStr = new string('A', testCapacity);
string resultStr = testStr.Replace("oldValue", "newValue", StringComparison.InvariantCultureIgnoreCase);
}
);
}
[Test]
public void TestOldValueIsOutOfMaxCapacity()
{
Assert.Throws(typeof(ArgumentException),
() =>
{
int testCapacity = new StringBuilder().MaxCapacity / 128 + 1;
string testStr = "Hello, World!";
string oldValue = new string('A', testCapacity);
string resultStr = testStr.Replace(oldValue, "newValue", StringComparison.InvariantCultureIgnoreCase);
}
);
}
[Test]
public void TestNewValueIsOutOfMaxCapacity()
{
Assert.Throws(typeof(ArgumentException),
() =>
{
int testCapacity = new StringBuilder().MaxCapacity / 128 + 1;
string testStr = "Hello, World!";
string newValue = new string('A', testCapacity);
string resultStr = testStr.Replace("oldValue", newValue, StringComparison.InvariantCultureIgnoreCase);
}
);
}
[Test]
public void TestResultStringIsOutOfMaxCapacity()
{
Assert.Throws(typeof(ArgumentOutOfRangeException),
() =>
{
string oldValue = "Hello, World!";
int testCapacity = new StringBuilder().MaxCapacity / 128 - oldValue.Length;
string testStr = oldValue + new string('A', testCapacity);
string newValue = "Hello, the New World!";
string resultStr = testStr.Replace(oldValue, newValue, StringComparison.InvariantCultureIgnoreCase);
}
);
}
}
}
答案 2 :(得分:0)
替换文本将不起作用,相反,您只需将范围标签放在搜索到的文本之前和之后。这可能需要进行如下更改。
Private Sub WebBrowser_DocumentCompleted(sender As Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser.DocumentCompleted
Dim doc2 As mshtml.IHTMLDocument2 = WebBrowser.Document.DomDocument
Dim ReplacementTag As String = "<span style='background-color: rgb(255, 255, 0);'>"
Dim strBuilder As StringBuilder = New StringBuilder(doc2.body.outerHTML)
Dim HTMLString As String = strBuilder.ToString()
If Me.m_NoteType = ExtractionNoteType.SearchResult Then
Dim SearchWords As New List(Of String)
SearchWords.AddRange(Me.txtSearch.Text.Trim.Split(" "))
For Each item As String In SearchWords
Dim index As Integer = HTMLString.IndexOf(item, 0, StringComparison.InvariantCultureIgnoreCase)
''If index > 0 Then
While (index > 0 AndAlso index < HTMLString.Length)
HTMLString = HTMLString.Insert(index, ReplacementTag)
HTMLString = HTMLString.Insert(index + item.Length + ReplacementTag.Length, "</span>")
index = HTMLString.IndexOf(item, index + item.Length + ReplacementTag.Length + 7, StringComparison.InvariantCultureIgnoreCase)
End While
''End If
''strBuilder.Replace(item, "<span style='background-color: rgb(255, 255, 0);'>" + item + "</span>")
Next
Else
''strBuilder.Replace("<span style='background-color: rgb(255, 255, 0);'>", "<span style='background-color: rgb(255, 255, 255);'>")
End If
doc2.body.innerHTML = HTMLString
End Sub