在C#中替换多个字符串元素

Chr*_*Kee 77 c# string refactoring immutability

有没有更好的方法来做到这一点......

MyString.Trim().Replace("&", "and").Replace(",", "").Replace("  ", " ")
         .Replace(" ", "-").Replace("'", "").Replace("/", "").ToLower();
Run Code Online (Sandbox Code Playgroud)

我已经扩展了字符串类以使其保持一个工作但是有更快的方法吗?

public static class StringExtension
{
    public static string clean(this string s)
    {
        return s.Replace("&", "and").Replace(",", "").Replace("  ", " ")
                .Replace(" ", "-").Replace("'", "").Replace(".", "")
                .Replace("eacute;", "é").ToLower();
    }
}
Run Code Online (Sandbox Code Playgroud)

只是为了好玩(以及停止评论中的论点),我已经推动了以下各种示例的基准测试.

https://gist.github.com/ChrisMcKee/5937656

正则表达式选项得分非常高; 字典选项最快; stringbuilder replace的long winded版本比short hand稍快.

小智 106

更快 - 没有.更有效 - 是的,如果您将使用该StringBuilder课程.在您的实现中,每个操作都会生成一个字符串的副本,在这种情况下可能会影响性 字符串是不可变对象,因此每个操作只返回修改后的副本.

如果您希望在多个Strings重要长度上主动调用此方法,那么将其实现"迁移"到StringBuilder类上可能会更好.有了它,任何修改都直接在该实例上执行,因此您可以节省不必要的复制操作.

public static class StringExtention
{
    public static string clean(this string s)
    {
        StringBuilder sb = new StringBuilder (s);

        sb.Replace("&", "and");
        sb.Replace(",", "");
        sb.Replace("  ", " ");
        sb.Replace(" ", "-");
        sb.Replace("'", "");
        sb.Replace(".", "");
        sb.Replace("eacute;", "é");

        return sb.ToString().ToLower();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在您的https://gist.github.com/ChrisMcKee/5937656基准测试中,字典测试未完成:它不会完成所有替换并且""替换"",而不是"".不做所有替换可能是原因,为什么它在基准测试中最快.正则表达式替换也不完整.但最重要的是你的字符串TestData是_very_ short.与接受的答案状态一样,字符串必须具有相当长的长度,以使StringBuilder具有优势.能否请用10kB,100kB和1MB的字符串重复基准测试? (3认同)
  • 为清楚起见,字典答案是最快的 http://stackoverflow.com/a/1321366/52912 (2认同)

Pao*_*sco 13

也许更具可读性?

    public static class StringExtension {

        private static Dictionary<string, string> _replacements = new Dictionary<string, string>();

        static StringExtension() {
            _replacements["&"] = "and";
            _replacements[","] = "";
            _replacements["  "] = " ";
            // etc...
        }

        public static string clean(this string s) {
            foreach (string to_replace in _replacements.Keys) {
                s = s.Replace(to_replace, _replacements[to_replace]);
            }
            return s;
        }
    }
Run Code Online (Sandbox Code Playgroud)

还添加New In Town关于StringBuilder的建议......

  • 它会更像这样:`private static Dictionary <string,string> _replacements = new Dictionary <string,string>(){{"&","and"},{",",""},{" ",""}/*etc*/};` (5认同)
  • -1:使用字典在这里没有任何意义。只需使用“List&lt;Tuple&lt;string,string&gt;&gt;”即可。这也改变了替换的顺序,并且不像`s.Replace("a").Replace("b").Replace("c")`那么快。不要用这个! (3认同)
  • 或者当然是...私有静态只读Dictionary &lt;string,string&gt;替换= new Dictionary &lt;string,string&gt;(){{“&”,“ and”},{“,”,“”},{“”, “”} / *等* /}; 公共静态字符串Clean(此字符串s){返回Replacements.Keys.Aggregate(s,(current,toReplace)=&gt; current.Replace(toReplace,Replacements [toReplace])); } (2认同)

The*_*iot 12

这将更有效:

public static class StringExtension
{
    public static string clean(this string s)
    {
        return new StringBuilder(s)
              .Replace("&", "and")
              .Replace(",", "")
              .Replace("  ", " ")
              .Replace(" ", "-")
              .Replace("'", "")
              .Replace(".", "")
              .Replace("eacute;", "é")
              .ToString()
              .ToLower();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这实际上比较慢.BenchmarkOverhead ... 13ms StringClean-user151323 ... 2843ms StringClean-TheVillageIdiot ... 2921ms重播不同但答案胜出https://gist.github.com/anonymous/5937596 (2认同)

Tim*_*imS 11

如果你只是在一个漂亮的解决方案之后并且不需要节省几纳秒,那么一些LINQ糖怎么样?

var input = "test1test2test3";
var replacements = new Dictionary<string, string> { { "1", "*" }, { "2", "_" }, { "3", "&" } };

var output = replacements.Aggregate(input, (current, replacement) => current.Replace(replacement.Key, replacement.Value));
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,您将功能语句定义为比程序语句“丑陋”。 (4认同)

And*_*nko 5

在建议的解决方案中可能有一件事可以优化。进行多次调用Replace()会使代码对同一字符串进行多次传递。对于很长的字符串,由于CPU缓存容量不足,解决方案可能会很慢。也许应该考虑一次更换多个字符串

  • 很多答案似乎都关心性能,在这种情况下这是最好的。它很简单,因为它只是字符串的[记录的重载](https://docs.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.replace?view=netframework-4.8#System_Text_RegularExpressions_Regex_Replace_System_String_System_String_System_Text_RegularExpressions_MatchEvaluator_) .根据匹配替换返回预期值的位置,在本例中,使用字典来匹配它们。应该简单易懂。 (2认同)
  • 从链接页面添加了代码,以防止如果链接页面死亡,此答案变得无用 (2认同)