从另一个字符串中修剪字符串的第一个和最后一个实例的最佳表现方式?

时间:2013-08-28 18:18:55

标签: c# string performance

我正在尝试从另一个字符串的开头和结尾修剪可变长度字符串的第一个实例,并且我正在努力想出一个理想的方法来执行此操作而不会在字符串上迭代太多次。

例如,假设我有

public string ParseValue(string value, string trimFromStart, string trimFromEnd)
{
    // ??
}

我打电话

var value = ParseValue("AAABBBCCCAAABBB", "AAAB", "BB");

然后我希望最终结果为value = "BBCCCAAB"

在速度和内存使用方面,最佳表现方式是什么?

2 个答案:

答案 0 :(得分:3)

不确定它是否是最好的:

public string ParseValue(string value, string trimFromStart, string trimFromEnd)
{
  var s = value.StartsWith(trimFromStart) ? value.Substring(trimFromStart.Length) : value;
  s = s.EndsWith(trimFromEnd) ? s.Substring(0,s.Length-trimFromEnd.Length) : s;      
  return s == value ? s : ParseValue(s, trimFromStart, trimFromEnd);
}

如果你想处理这个例子来制作ParseValue("ABCDE","ABC","CDE") == "",这个代码可以正常工作,看起来你不想修剪两次,所以我在这里注释了recursive code版本:

public string ParseValue(string value, string trimFromStart, string trimFromEnd){
   bool startsWith = value.StartsWith(trimFromStart);
   bool endsWith = value.EndsWith(trimFromEnd);
   int startLength = trimFromStart.Length;
   int endLength = trimFromEnd.Length;
   if (startsWith && endsWith && value.Length <= startLength + endLength) return "";
   var s = startsWith ? value.Substring(startLength) : value;
   s = endsWith ? s.Substring(0, s.Length - endLength) : s;
   return s;// == value ? s : ParseValue(s, trimFromStart, trimFromEnd);
}

答案 1 :(得分:1)

你已经回答了,但是这里有一个实现(可能会被调整),它涵盖了更多的边缘情况。

public string ParseValue(string value, string trimFromStart, string trimFromEnd)
{
    int valueLength = value.Length;
    int trimStartAmount = value.StartsWith(trimFromStart) 
        ? trimFromStart.Length 
        : 0;

    int trimFromEndIndex = valueLength;
    int trimEndAmount = 0;

    if (value.EndsWith(trimFromEnd))
    {
        trimFromEndIndex = valueLength - trimFromEnd.Length;
        trimEndAmount = trimFromEnd.Length;
    }

    if (trimStartAmount >= trimFromEndIndex)
        return "";

    if (trimStartAmount == 0 && trimEndAmount == 0)
        return value;

    return value.Substring(trimStartAmount, valueLength - trimStartAmount - trimEndAmount);
}

试验:

Assert.AreEqual("C", ParseValue("ABCDE", "AB", "DE"));
Assert.AreEqual("ABC", ParseValue("ABCDE", "ABCDEF", "DE"));
Assert.AreEqual("DE", ParseValue("ABCDE", "ABC", "ABCDEF"));
Assert.AreEqual("", ParseValue("ABCDE", "ABC", "CDE"));
Assert.AreEqual("", ParseValue("ABCDE", "ABC", "DE"));
Assert.AreEqual("BBCCCAAAB", ParseValue("AAABBBCCCAAABBB", "AAAB", "BB"));

accepted answer在测试2,3,4上失败,并在两个字符串重叠时抛出异常。