C# 删除字符串结尾处系列的所有实例

C# 删除字符串结尾处系列的所有实例,c#,regex,string,trim,C#,Regex,String,Trim,假设我们有一个返回字符数组定义的程序——这样我们就可以将它复制粘贴到其他一些C#代码中。一个可能的结果是以下字符串: // Current output: return "CharArray = { {}, {123}, {}, {3 3}, {111}, {}, {}" + "};"; 现在,我们要消除CharArray末尾的多余空行,同时在开头或中间留下任何空行: // Desired output: "CharArray = { {}, {123}, {}, {3 3}, {111}"

假设我们有一个返回字符数组定义的程序——这样我们就可以将它复制粘贴到其他一些C#代码中。一个可能的结果是以下字符串:

// Current output:
return "CharArray = { {}, {123}, {}, {3 3}, {111}, {}, {}" + "};";
现在,我们要消除CharArray末尾的多余空行,同时在开头或中间留下任何空行:

// Desired output:
"CharArray = { {}, {123}, {}, {3 3}, {111}" + "};";
(由于间距的原因,数据之前或之间的任何空行都是必要的,但末尾的空白对我们的代码没有任何作用。)

由于最后一个括号和分号直到操作完成后才添加,因此最简单的方法似乎是从字符串中删除“,{}”的所有尾随实例。我目前的解决方案是一个非常开箱即用的替换和修剪组合

// Red-Green solution:
return output.Replace(", {}", "!").TrimEnd('!').Replace("!", ", {}") + "};";
…这肯定会返回正确的结果,但是很长,让读者感到困惑,并且很可能在第一次阅读时让您畏缩

此外,我通常用于此类问题的Regex.Replace只删除一个空行(因为在字符串的末尾只存在一个空行),我宁愿不必通过循环将其输入:

// Sub-par solution: (birdie solution?)
 return Regex.Replace(testString, ", {}$", "") + "};";


如何最好地仅从字符串末尾删除一系列字符的所有实例?我更喜欢既可读又不太慢或在机器上费力的结果。(据用户目前所知,按下按钮后会立即返回。)

您可以使用正则表达式:

return "\n" + Regex.Replace(testString, "(, {})+$", "") + "};";
这也将替换搜索字符串的多次出现

+
运算符的意思是:前面的表达式出现一次或多次

请尝试以下操作:

    string TrimEndMultiple(string str, string end)
    {
        int lenend = end.Length;

        int start = str.Length - lenend;

        while (String.CompareOrdinal(str, start, end, 0, lenend) == 0)
        {
            start -= lenend;
        }

        // Addendum:
        return str.Substring(0, start + lenend);
    }

我试过了,TrimEndMultiple快20倍:

    [MethodImplAttribute(MethodImplOptions.NoInlining)] 
    static string TrimEndMutiple(string str, string end)
    {
        int lenend = end.Length;

        int start = str.Length - lenend;

        while (String.CompareOrdinal(str, start, end, 0, lenend) == 0)
        {
            start -= lenend;
        }

        return str.Substring(0, start + lenend);
    } 

    static void Main(string[] args)
    {
        string s = "CharArray = { {}, {123}, {}, {3 3}, {111}, {}, {}";

        Regex reg = new Regex("(, {})+$", RegexOptions.Compiled);

        string s1 = reg.Replace(s, "");
        string s2 = TrimEndMutiple(s, ", {}");

        Stopwatch watch = new Stopwatch();

        int count = 1000 * 100;

        watch.Start();

        for (int i = 0; i < count; i++)
        {
            s1 = reg.Replace(s, "");
        }

        watch.Stop();

        Console.WriteLine("{0} {1,9:N3} ms", s1, watch.ElapsedTicks * 1000.0 / Stopwatch.Frequency);

        watch.Restart();

        for (int i = 0; i < count; i++)
        {
            s2 = TrimEndMutiple(s, ", {}"); 
        }

        watch.Stop();

        Console.WriteLine("{0} {1,9:N3} ms", s2, watch.ElapsedTicks * 1000.0 / Stopwatch.Frequency);
    }

当然,您的答案将返回正确的值,但可读性和性能会降低。对于我的问题和类似的问题,我推荐Fix's Fix。它是更通用的解决方案,而且效率更高(除非您使用不安全的代码)。测量一下。啊,划伤它——仔细检查,它卡在while循环上了。(我只是假设这需要很长时间。)循环现在运行良好(尽管您的输出与我想要的正好相反。)即使如此,它似乎仍然比两个选项都慢,重复时最明显,但一次调用几乎检测不到差异。
CharArray = { {}, {123}, {}, {3 3}, {111}   298.014 ms
CharArray = { {}, {123}, {}, {3 3}, {111}    15.495 ms