2010-05-14 20 views
6

J'ai construit un petit formulaire asp.net qui cherche quelque chose et affiche les résultats. Je veux mettre en évidence la chaîne de recherche dans les résultats de recherche. Exemple:cas chaîne insensible qui fonctionne correctement avec des ligatures comme "ß" <=> "ss"

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

Le code que j'ai dit ceci:

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); 
} 

Je travaille surtout essayer mais par exemple avec HighlightSubstring("ß", "ss"). Cela se bloque car en Allemagne "ß" et "ss" sont considérés comme égaux par la méthode IndexOf, mais ils ont une longueur différente!

Maintenant ce serait bien s'il y avait un moyen de savoir combien de temps la correspondance en "texte" est. Rappelez-vous que cette longueur peut être != substring.Length.

Alors, comment puis-je trouver la longueur de la correspondance que IndexOf produit en présence de ligatures et de caractères de langage exotiques (ligatures dans ce cas)?

+0

Je me demandais juste: pourquoi seulement mettre en évidence le premier "p" dans "apple"? – FrustratedWithFormsDesigner

+0

Vous avez raison, je vais modifier cela pour mettre en évidence tous les matchs ;-) thx. – usr

+0

Est-ce que 'StringComparison.OrdinalIgnoreCase' fait ce que vous voulez? – Gabe

Répondre

2

Cela peut ne pas répondre directement à votre question, mais peut-être va résoudre votre problème réel.

Pourquoi ne pas remplacer à la place?

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>"); 
} 

Mais qu'en est-il de la culture? Si vous spécifiez un Regex comme insensible à la casse, il est sensible à la culture par défaut selon http://msdn.microsoft.com/en-us/library/z0sbec17.aspx.

+0

J'ai upvoted ceci, parce que c'est une solution, mais je ne l'utiliserai pas parce que la performance de créer une nouvelle regex environ 100 fois par demande sera trop pour mes fins. – usr

+0

Il est tout à fait possible de résoudre le problème de recompilation si vous devez utiliser le Regex plusieurs fois par requête (je suppose qu'il y a plusieurs chaînes de texte à vérifier?). Je peux penser à deux façons. Tout d'abord, vous pouvez utiliser la méthode statique Regex.Replace plutôt que de créer la méthode d'instance comme je le fais dans le code. En utilisant la méthode statique, .NET met en cache l'expression régulière (voir http://msdn.microsoft.com/fr-fr/library/8zbs0h2f.aspx). Ou, créez l'expression régulière en dehors de la méthode HighlightString et réutilisez l'expression rationnelle pour chaque remplacement. Enfin, si le problème concerne plusieurs sous-chaînes, créez une expression rationnelle qui les combine. – Andrew