2010-05-14 7 views
6

Ich habe eine kleine asp.net Formular erstellen, die nach etwas sucht und zeigt die Ergebnisse. Ich möchte den Suchstring innerhalb der Suchergebnisse hervorheben. Beispiel:Fall insenStive Zeichenfolge ersetzen, die korrekt funktioniert mit Ligaturen wie "ß" <=> "ss"

Query: "p" 
Results: a<b>p</b>ple, banana, <b>p</b>lum 

Der Code, den ich habe so geht:

public static string HighlightSubstring(string text, string substring) 
{ 
var index = text.IndexOf(substring, StringComparison.CurrentCultureIgnoreCase); 
if(index == -1) return HttpUtility.HtmlEncode(text); 
string p0, p1, p2; 
text.SplitAt(index, index + substring.Length, out p0, out p1, out p2); 
return HttpUtility.HtmlEncode(p0) + "<b>" + HttpUtility.HtmlEncode(p1) + "</b>" + HttpUtility.HtmlEncode(p2); 
} 

ich funktioniert meistens aber versuchen, es zum Beispiel mit HighlightSubstring("ß", "ss"). Dies stürzt ab, weil in Deutschland "ß" und "ss" gleich von der IndexOf Methode sind, aber sie haben unterschiedliche Länge!

Nun wäre das in Ordnung, wenn es eine Möglichkeit gäbe herauszufinden, wie lange die Übereinstimmung in "text" ist. Denken Sie daran, dass diese Länge sein kann.

Also wie finde ich die Länge der Übereinstimmung, die IndexOf in Gegenwart von Ligaturen und exotischen Sprache Zeichen (Ligaturen in diesem Fall) produziert?

+0

Ich frage mich nur: Warum nur das erste "p" in "Apfel" hervorheben? – FrustratedWithFormsDesigner

+0

Du hast Recht, ich werde das ändern, um alle Übereinstimmungen hervorzuheben ;-) thx. – usr

+0

Funktioniert 'StringComparison.OrdinalIgnoreCase', was Sie wollen? – Gabe

Antwort

2

Dies beantwortet möglicherweise nicht direkt Ihre Frage, aber vielleicht wird Ihr tatsächliches Problem lösen.

Warum nicht ersetzen statt?

using System.Text.RegularExpressions; 

public static string HighlightString(string text, string substring) 
{ 
    Regex r = new Regex(Regex.Escape(HttpUtility.HtmlEncode(substring)), 
         RegexOptions.IgnoreCase); 
    return r.Replace(HttpUtility.HtmlEncode(text), @"<b>$&</b>"); 
} 

Aber was ist mit der Kultur? Wenn Sie eine Regex als case-insensitive angeben, ist sie standardmäßig gemäß http://msdn.microsoft.com/en-us/library/z0sbec17.aspx kultursensitiv.

+0

Ich habe das upgestimmt, weil es eine Lösung ist, aber ich werde es nicht verwenden, weil die Leistung der Erstellung eines frischen Regex etwa 100 Mal pro Anfrage für meine Zwecke zu viel ist. – usr

+0

Es ist durchaus möglich, das Problem der Neukompilierung zu lösen, wenn Sie die Regex mehrmals pro Anfrage verwenden müssen (ich nehme an, dass es mehrere Textzeichenfolgen gibt, die überprüft werden müssen?). Ich kann mir zwei Möglichkeiten vorstellen. Erstens könnten Sie die statische Regex.Replace-Methode verwenden, anstatt die Instanzmethode wie im Code zu erstellen. Die Verwendung der statischen Methode bewirkt, dass .NET die Regex zwischenspeichert (siehe http://msdn.microsoft.com/en-us/library/8zbs0h2f.aspx). Oder erstellen Sie die Regex außerhalb der HighlightString-Methode und verwenden Sie die Regex für jede Ersetzung erneut. Wenn das Problem mehrere Teilstrings sind, erstellen Sie schließlich eine Regex, die sie kombiniert. – Andrew