从另一个字符串修剪字符串的第一个和最后一个实例的最佳执行方式

本文关键字:字符串 最佳 实例 执行 方式 最后一个 第一个 另一个 修剪 | 更新日期: 2023-09-27 18:29:19

我正试图从另一个字符串的开始和结束处修剪可变长度字符串的第一个实例,并且正在努力找出一种理想的方法来做到这一点,而不必对该字符串进行太多次迭代。

例如,假设我有

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

我打电话给

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

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

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

从另一个字符串修剪字符串的第一个和最后一个实例的最佳执行方式

不确定它是否是最好的:

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

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

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中失败,并且当两个字符串重叠时抛出异常。