【问题标题】:Using StringComparer with StringBuilder to search for a string使用 StringComparer 和 StringBuilder 搜索字符串
【发布时间】:2015-06-18 21:50:28
【问题描述】:

我需要使用全球化规则来搜索文档中所有出现的字符串。伪代码为:

var searchText = "Hello, World";
var compareInfo = new CultureInfo("en-US").CompareInfo;

DocumentIterator start = null; // the start position if a match occurs
var sb = new StringBuilder();

// the document is not a string, but exposes an iterator to its content
for (var iter = doc.Start(); iter.IsValid(); ++iter)
{
    start = start ?? iter; // the start of the potential match

    var ch = iter.GetChar(); 
    sb.Append(ch);

    if (compareInfo.Compare(searchText, sb.ToString()) == 0) // exact match
    {
        Console.WriteLine($"match at {start}-{iter}");
        // not shown: continue to search for more occurrences.
    }
    else if (!compareInfo.IsPrefix(criteria.Text, sb.ToString()))
    {
        // restart the search from the character immediately following start
        sb.Clear();
        iter = start; // this gets incremented immediately
        start = null;
    }
}

这将文化敏感字符串匹配的艰巨工作委托给 CompareInfo。

但是,代码实现的类流过程存在性能问题,因为它在每次迭代中调用 StringBuilder.ToString(),从而破坏了 StringBuilder 的性能优势。

问题:如何有效地进行此搜索?

【问题讨论】:

  • 为什么不能使用 compareInfo.IndexOf(searchText, sb) where sb - full document?
  • @Oleg,我已经编辑了代码以更清楚地表明文档不是字符串,而是将迭代器暴露给其字符内容。

标签: c# string search stringbuilder culture


【解决方案1】:

那么为什么不先将整个文档复制到一个字符串生成器,使用 1 ToString()。然后只需使用类似的方案来迭代所有可能的值。使用 compareInfo.Compare(criteria.Text, 0, criteria.Text.Length, docString, startIndex, checkLength)

【讨论】:

  • 好的,所以我阅读了有关数据太大而无法一次全部复制到字符串中的评论,所以请忽略它。我认为您需要按照以下建议进行一些分块。只需选择任意大小转储为字符串,然后调用搜索函数,一旦找到匹配项,您就可以清除 sb 并从新位置重新开始。
【解决方案2】:

为什么不使用对文化敏感的字符串 IndexOf,然后使用 indexOf 遍历您的文档以开始下一个搜索,直到找不到任何内容 请参阅first answer here

启动它所需要做的就是设置当前的文化。我假设do 循环很明显。

【讨论】:

  • 文档不是字符串——这就是我在伪代码中使用 doc[i] 的原因。我可以将它读入一个大型 StringBuilder 中,但这在很多方面都有问题 - a)内存成本,b)迭代器实际上不是我展示的简单整数 - 所以我也必须缓存它们.
  • 您是否无法对字符串构建器进行足够的阅读以使大小可用,然后将任何先前搜索的尾部作为新字符串构建器的开始。这样您就不需要逐个字符地进行迭代,而只需要在搜索文本的位置上进行迭代
  • 如何避免在循环中调用 StringBuilder.ToString() ?其他问题也浮现在脑海中。你能发布一个你认为可行的代码版本吗?干杯
猜你喜欢
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 2015-04-29
  • 2016-05-03
  • 2017-07-23
  • 2010-09-09
相关资源
最近更新 更多