是否多次调用string.Replace()的效率低于在.NET中对Regex方法的单次调用?

时间:2010-07-13 16:21:16

标签: .net

我想在字符串中替换大约8个字符。

使用Regex方法或仅使用多次调用string.Replace()

会更有效吗?

我正在替换可能出现的大约7个字符,而不是全部是下划线。字符可以出现在字符串中的任何位置,而不是按特定顺序等。

6 个答案:

答案 0 :(得分:8)

除非您确实需要匹配正则表达式,否则不要使用Regex类。让String类型执行直接文本或字符匹配更有效率,如果这是你创建的正则表达式。

Regex类比简单字符或字符串匹配更强大。这种力量不是免费的。使用完整的正则表达式来匹配字符/字符串是过度的。这相当于使用高功率炸药从你的草坪上取下一只蚂蚁,当你的鞋子做得很好。

答案 1 :(得分:8)

您无需多次调用string.Replace() - 它会在一次传递中替换所有出现的事件。 See the MSDN documentation。如果要替换字符串中的不同输入序列,您只需要进行多次调用(这可能是您在问题中暗示的内容)。

在这种情况下,我会使用string.Splitstring.Join

var replaced = string.Join( "_", input.Split( new[]{'x','y','z'} ) );

这将在字符“x”,“y”或“z”之一出现的每个位置拆分字符串(替换为您的集合),并使用“_”字符重新加入片段 - 有效地替换原件。这种方法 NOT 必然比多次调用string.Replace更有效 - 这取决于输入字符串的长度,要替换的字符的出现次数等等。您需要使用真实数据进行分析,以确定哪些更快。然而,的方法是使代码更简洁。

就性能而言 - 我会先使用最简单,最易读的解决方案,如果测试显示出问题 - 那么我会介绍并决定采用哪种替代解决方案(如果有的话) )。除非有充分的理由不这样做,否则在编写代码时我的个人优先事项是:

  1. 纠正错误。
  2. 说清楚。
  3. 简明扼要。
  4. 快点。
  5. ..按此顺序。

答案 2 :(得分:4)

同时,根据这些字符串的长度和可能需要替换的字符数,您应该使用StringBuilder对象而不是字符串。

字符串是不可变的,因此在每次替换时,您将使用下划线创建一个新字符串。 StringBuilder类对字符串对象的多次更改更有效。

答案 3 :(得分:1)

12蜱与1200蜱对比40蜱

public class Program
{
    static void Main(string[] args)
    {
        string str = "abcdefghijklmnopqrstuvxywz0123456789_";
        string replace = "aez01234567";

        DoReplace(str, replace); // 12
        DoRegex(str, replace);   // 1200
        DoJoin(str, replace);    // 40

        Console.ReadKey();
    }

    public static void DoReplace(string str, string replace)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < replace.Length; ++i)
        {
            str = str.Replace(replace[i], '*');
        }
        sw.Stop();
        Console.WriteLine("Multiple replace (" + sw.ElapsedTicks + ") => " + str);
    }

    public static void DoRegex(string str, string replace)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        str = Regex.Replace(str, "[" + replace + "]", "*");
        sw.Stop();
        Console.WriteLine("Regex replace (" + sw.ElapsedTicks + ") => " + str);
    }

    public static void DoJoin(string str, string replace)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        str = string.Join("*", str.Split(replace.ToCharArray()));
        sw.Stop();
        Console.WriteLine("Join replace (" + sw.ElapsedTicks + ") => " + str);
    }
}

我想循环中的简单替换更快......

<强>更新 包括LBushkin的方法

答案 4 :(得分:0)

没有实际分析它,我会说使用正则表达式更快,因为字符串只循环一次。我猜每个string.replace循环整个字符串

yourString = Regex.Replace(yourString, @"[uiae]", @"_"); // replace u, i, a and e with an underscore

答案 5 :(得分:0)

扩展LoneDeveloper's answer,您可以编写自己的扩展方法,立即进行一系列替换:

public static ReplaceAll(this string text, IEnumerable<string> needles, string replacement)
{
    var sb = new StringBuilder(text);
    foreach (string needle in needles)
    {
        sb.Replace(needle, replacement);
    }

    return sb.ToString();
}

要调用此代码,您只需执行以下操作:

var needles = new string[] { "a", "b", "c" };

string abcRemoved = "abcdefg".ReplaceAll(needles, "_");