【问题标题】:Alternative to multiple String.Replaces [duplicate]替代多个 String.Replaces [重复]
【发布时间】:2012-08-13 23:52:14
【问题描述】:

我的代码连续多次使用String.Replace

mystring = mystring.Replace("somestring", variable1);
mystring = mystring.Replace("somestring2", variable2);
mystring = mystring.Replace("somestring3", variable1);

我怀疑有更好更快的方法来做到这一点。你有什么建议?

【问题讨论】:

  • 如果variable1 包含文本"somestring2",那么您的首选行为是什么?或者如果variable1"g2"mystring"somestrinsomestring",那么首选的行为是什么?

标签: c# string replace


【解决方案1】:

对于“简单”的替代方案,只需使用 StringBuilder....

StringBuilder sb = new StringBuilder("11223344");

string myString =
    sb
      .Replace("1", string.Empty)
      .Replace("2", string.Empty)
      .Replace("3", string.Empty)
      .ToString();

【讨论】:

  • 这样更容易吗?我看到的唯一好处是它可以减少对 GC 的压力。
  • @Daniel Hilgarth 我所说的“更简单”的意思是实现起来仍然很简单,但是在 StringBuiler 上将替换链接在一起比在常规字符串上调用它“更好更快”并且不包括下面列出的一些正则表达式解决方案的复杂性。
  • 这似乎是所提出的解决方案中可读性最强的。
  • 如果需要设置条件就不好了
  • 答案是 44 吗?
【解决方案2】:

我们是否正在设法使这更难了解正在发生的事情?

如果是这样,正则表达式是你的朋友

var replacements = new Dictionary<string,string>()
{
   {"somestring",someVariable1},
   {"anotherstring",someVariable2}
};

var regex = new Regex(String.Join("|",replacements.Keys.Select(k => Regex.Escape(k))));
var replaced = regex.Replace(input,m => replacements[m.Value]);

直播:http://rextester.com/SXXB8348

【讨论】:

  • 看起来不错,但是在编译正则表达式时,您需要在 dic 键周围调用 Regex.Escape。另请注意,它在技术上不会做同样的事情。它可能适用于 OP 的测试用例,但理论上,如果您有类似的情况,将“1”替换为“2”,然后将“2”替换为“3”,OP 的代码将导致每个“1”变为“3”而你的最终会导致“2”。只要您实际上没有用 OP 的示例替换之前迭代中已替换的内容,那么这将正常工作。
  • @Servy - 你说得很好。但是,我的第一句话应该指出,这是一种非常糟糕的多次替换方式。
  • @Jamiec:这有什么问题?它可能只需要读取字符串一次,只需复制字符串一次,让您轻松查找整个单词,让您对单词进行适当的大写,并让您执行转义字符串之类的操作(例如&amp;amp;=> &amp;amp;, "=>&amp;quot;) 无需担心替换发生的顺序。
  • 这(不幸的是)比多次调用 string.Replace() 慢得多。我也在寻找一种更快的方法来做到这一点;多次循环一个字符串似乎很浪费。
  • 此 RegEx 解决方案只通过一次即可正确替换所有项目。在某些情况下(比如我的),这是唯一的选项,调用 .Replace 不起作用。为什么?考虑变量 1 部分包含字符串“somestring2”的情况。然后第二个 .Replace 最终会破坏您想要替换的第一件事,等等。
【解决方案3】:

您至少可以将这些语句链接起来:

mystring = mystring.Replace("somestring", variable1)
                   .Replace("somestring2", variable2)
                   .Replace("somestring3", variable3); 

【讨论】:

    【解决方案4】:

    拨打Replace 三次不仅是一个有效的答案,它可能是首选:

    RegEx 需要三个步骤:解析、执行、公式化。但是String.Replace 是硬编码的,因此在许多情况下它具有出色的速度。复杂的 RegEx 不如格式良好的 Replace 语句链具有可读性。 (比较Jonathan的解决方案和Daniel的解决方案)

    如果您仍然不相信Replace 更适合您的情况,那就来一场比赛吧!并排尝试这两种方法并使用Stopwatch 来查看您在使用数据时节省了多少毫秒。

    但是DON'T optimize prematurely!任何开发人员都更喜欢可读性和可维护性,而不是执行速度快三毫秒的神秘意大利面条。

    【讨论】:

      【解决方案5】:

      这篇文章Regex: replace multiple strings in a single pass with C#可能会有所帮助:

      static string MultipleReplace(string text, Dictionary replacements) {
          return Regex.Replace(text, 
              "(" + String.Join("|", adict.Keys.ToArray()) + ")",
              delegate(Match m) { return replacements[m.Value]; }
          );
      }
      
      // somewhere else in code
      string temp = "Jonathan Smith is a developer";
      adict.Add("Jonathan", "David");
      adict.Add("Smith", "Seruyange");
      string rep = MultipleReplace(temp, adict);
      

      【讨论】:

      • 这与 Jamiec 的回答基本相同,但没有(必需的)转义。
      【解决方案6】:

      取决于您的数据的组织方式(您要替换的内容)或您拥有的数据数量;数组和循环可能是个好方法。

      string[] replaceThese = {"1", "2", "3"};
      string data = "replace1allthe2numbers3";
      
      foreach (string curr in replaceThese)
      {
          data = data.Replace(curr, string.Empty);
      }
      

      【讨论】:

        【解决方案7】:

        如果您不想使用 RegEx,请将此类添加到您的项目中,
        它使用扩展方法“MultipleReplace”:

        public static class StringExtender
        {
            public static string MultipleReplace(this string text, Dictionary<string, string> replacements)
            {
                string retVal = text;
                foreach (string textToReplace in replacements.Keys)
                {
                    retVal = retVal.Replace(textToReplace, replacements[textToReplace]);
                }
                return retVal;
            }
        }
        

        那么你就可以使用这段代码了:

         string mystring = "foobar";
        
         Dictionary<string, string> stringsToReplace = new Dictionary<string,string>();
         stringsToReplace.Add("somestring", variable1);
         stringsToReplace.Add("somestring2", variable2);
         stringsToReplace.Add("somestring3", variable1);
        
         mystring = mystring.MultipleReplace(stringsToReplace);
        

        【讨论】:

        • 赞成这个。它允许您从数据表中构建过滤器,这非常有用。所以当你有很多过滤器(在我的例子中是 50 个)并且你有 1k 个句子要通过时,这就是猫的喵喵声。
        【解决方案8】:

        我首选的方法是使用Regex 的强大功能来解决多重替换问题。这种方法的唯一问题是您只能选择一个 string 来替换。

        以下内容会将所有'/'':' 替换为'-' 以生成有效的文件名。

        Regex.Replace("invalid:file/name.txt", @"[/:]", "-");
        

        【讨论】:

          猜你喜欢
          • 2019-02-16
          • 2022-01-09
          • 1970-01-01
          • 2019-08-10
          • 2015-05-30
          • 2011-12-08
          • 2013-04-08
          • 2016-12-28
          相关资源
          最近更新 更多