【问题标题】:case insenstive string replace that correctly works with ligatures like "ß" <=> "ss"不区分大小写的字符串替换正确地适用于像“ß”<=>“ss”这样的连字
【发布时间】:2010-05-14 15:32:35
【问题描述】:

我已经构建了一个小型 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")。这会崩溃,因为在德国,IndexOf 方法认为 "ß" 和 "ss" 相等但它们的长度不同

现在,如果有办法找出“文本”中的匹配项有多长,那就没问题了。请记住,这个长度可以是!= substring.Length

那么我如何找出IndexOf 在存在连字和外来语言字符(本例中为连字)的情况下产生的匹配长度?

【问题讨论】:

  • 只是想知道:为什么只突出“apple”中的第一个“p”?
  • 你说得对,我会修改它以突出显示所有匹配项 ;-) thx.
  • StringComparison.OrdinalIgnoreCase 做你想做的事吗?

标签: .net encoding localization culture cultureinfo


【解决方案1】:

这可能不会直接回答您的问题,但可能会解决您的实际问题。

为什么不代替呢?

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 区分区域性。

【讨论】:

  • 我赞成这个,因为它是一个解决方案,但我不会使用它,因为对于我的目的来说,为每个请求创建大约 100 次新的正则表达式的性能将太多。
  • 如果每个请求必须多次使用正则表达式,很有可能解决重新编译问题(我认为有多个文本字符串要检查?)。我可以想到两种方法。首先,您可以使用静态 Regex.Replace 方法,而不是像我在代码中那样创建实例方法。使用静态方法会导致 .NET 缓存正则表达式(请参阅msdn.microsoft.com/en-us/library/8zbs0h2f.aspx)。或者,在 HighlightString 方法之外创建正则表达式并为每个替换重用正则表达式。最后,如果问题是多个子字符串,请创建一个组合它们的正则表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 2015-01-22
  • 2014-04-11
相关资源
最近更新 更多