замена строки без учета регистра, которая корректно работает с лигатурами, такими как "ß" <=> "ss" - PullRequest
6 голосов
/ 14 мая 2010

Я создал небольшую форму asp.net, которая что-то ищет и отображает результаты. Я хочу выделить строку поиска в результатах поиска. Пример:

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

Код, который у меня есть, выглядит так:

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

Я в основном работаю, но попробую, например, с HighlightSubstring("ß", "ss"). Это происходит сбой, потому что в Германии "ß" и "ss" считаются равными по методу IndexOf, , но имеют разную длину !

Теперь это было бы нормально, если бы был способ узнать, как долго совпадение в "тексте". Помните, что эта длина может быть != substring.Length.

Итак, как мне узнать длину совпадения, которое IndexOf производит в присутствии лигатур и символов экзотического языка (в данном случае лигатур)?

1 Ответ

2 голосов
/ 15 мая 2010

Это может не дать прямого ответа на ваш вопрос, но, возможно, решит вашу актуальную проблему.

Почему бы не заменить вместо этого?

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

Но как насчет культуры? Если вы указываете Regex как нечувствительный к регистру, он по умолчанию учитывает культуру в соответствии с http://msdn.microsoft.com/en-us/library/z0sbec17.aspx.

...