0

我正在尝试从另一个字符串的开头和结尾修剪可变长度字符串的第一个实例,并且正在努力找出一种理想的方法来做到这一点,而无需多次迭代字符串。

例如,假设我有

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

我打电话给

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

那么我希望最终结果是value = "BBCCCAAB"

就速度和内存使用而言,实现这一目标的最佳执行方式是什么?

4

2 回答 2

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);
}

如果你想处理例如 make 的情况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);
}
于 2013-08-28T18:24:55.447 回答
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"));

接受的答案在测试 2、3、4 中失败,并在两个字符串重叠时引发异常。

于 2013-08-28T19:42:06.230 回答