【问题标题】:Best way to replace text in string替换字符串中文本的最佳方法
【发布时间】:2015-10-09 19:02:36
【问题描述】:

寻找更好的算法/技术来替换字符串变量中的字符串。我必须遍历未知数量的数据库记录,并且对于每一个,我都需要替换字符串变量中的一些文本。现在看起来像这样,但必须有更好的方法:

using (eds ctx = new eds())
{
    string targetText = "This is a sample string with words that will get replaced based on data pulled from the database";

    List<parameter> lstParameters = ctx.ciParameters.ToList();
    foreach (parameter in lstParameters)
    {
        string searchKey = parameter.searchKey;
        string newValue = parameter.value;
        targetText = targetText.Replace(searchKey, newValue);
    }
}

据我了解,这并不好,因为我在循环中一遍又一遍地编写了 targetText 变量。但是,我不确定查找和替换的结构如何......

感谢任何反馈。

【问题讨论】:

  • 您担心性能或某些替换值可能再次被替换 ("asd".Replace("a", "s").Replace("s", "d"))?。

标签: c#


【解决方案1】:

必须有更好的方法

字符串是不可变的——你不能“改变”它们——你所能做的就是创建一个 new 字符串并替换变量值(这并不像你想象的那么糟糕)。您可以按照其他建议尝试使用 StringBuilder,但不能保证 100% 提高您的性能。

可以更改您的算法以循环遍历 targetText 中的“单词”,查看 parameters 中是否有匹配项,获取“替换”值并构建一个新字符串,但我怀疑额外的查找会比多次重新创建字符串值花费更多。

在任何情况下,都应该考虑两个重要的性能改进原则:

  • 首先从应用程序的 最慢 部分开始 - 您可能会看到一些改进,但如果它没有显着提高 整体 性能,那么这并不重要
  • 了解特定更改是否会提高您的绩效(以及提高多少)的唯一方法是尝试两种方式并对其进行衡量。

【讨论】:

  • 为什么在某些情况下 StringBuilder.Replace() 不是一个好的选择?它是可变的,开销可能并不总是一个问题。如果我错了,请纠正我
  • @MarcWittmann 可能是这样,我会修改我的答案以使其不那么绝对。
【解决方案2】:

实际上, 有一个更好的答案,假设您要进行大量替换。您可以使用StringBuilder。如您所知,字符串是不可变的。正如您所说,您在循环中一遍又一遍地创建字符串。

如果您将字符串转换为StringBuilder

StringBuilder s = new StringBuilder(s, s.Length*2); // Adjust the capacity based on how much bigger you think the string will get due to replacements. The more accurate your estimate, the better this will perform.

  foreach (parameter in lstParameters)
    {
        s.Replace(parameter.searchKey, parameter.value);
    }
  string targetString = s.ToString();

现在需要注意的是,如果您的列表中只有 2-3 项,这可能不会更好。 this question 的答案很好地分析了您可以期待看到的性能改进。

【讨论】:

    【解决方案3】:

    StringBuilder 将具有更少的内存开销和更好的性能,尤其是在大字符串上。 String.Replace() vs. StringBuilder.Replace()

    using (eds ctx = new eds())
    {
        string targetText = "This is a sample string with words that will get replaced based on data pulled from the database";
    
        var builder = new StringBuilder(targetText);
    
        List<parameter> lstParameters = ctx.ciParameters.ToList();
        foreach (parameter in lstParameters)
        {
            string searchKey = parameter.searchKey;
            string newValue = parameter.value;
            targetText = builder.Replace(searchKey, newValue);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 2011-10-16
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 2016-08-10
      相关资源
      最近更新 更多