Trim string from the end of a string in .NET - why is this missing?

前端 未结 13 1339
夕颜
夕颜 2020-12-13 12:08

I need this all the time and am constantly frustrated that the Trim(), TrimStart() and TrimEnd() functions don\'t take strings as inputs. You call EndsWith() on a string, an

13条回答
  •  独厮守ぢ
    2020-12-13 12:33

    I recently needed a high performance way to remove single or multiple instances of a string from the start/end of a string. This implementation I came up with is O(n) on the length of the string, avoids expensive allocations, and does not call SubString at all by using a span.

    No Substring hack! (Well, now that I edited my post).

        public static string Trim(this string source, string whatToTrim, int count = -1) 
            => Trim(source, whatToTrim, true, true, count);
    
        public static string TrimStart(this string source, string whatToTrim, int count = -1) 
            => Trim(source, whatToTrim, true, false, count);
    
        public static string TrimEnd(this string source, string whatToTrim, int count = -1) 
            => Trim(source, whatToTrim, false, true, count);
    
        public static string Trim(this string source, string whatToTrim, bool trimStart, bool trimEnd, int numberOfOccurrences)
        {
            // source.IsNotNull(nameof(source));  <-- guard method, define your own
            // whatToTrim.IsNotNull(nameof(whatToTrim));  <-- "
    
            if (numberOfOccurrences == 0 
                || (!trimStart && !trimEnd) 
                || whatToTrim.Length == 0 
                || source.Length < whatToTrim.Length)
                return source;
    
            int start = 0, end = source.Length - 1, trimlen = whatToTrim.Length;
    
            if (trimStart)
                for (int count = 0; start < source.Length; start += trimlen, count++)
                {
                    if (numberOfOccurrences > 0 && count == numberOfOccurrences)
                        break;
                    for (int i = 0; i < trimlen; i++)
                        if ((source[start + i] != whatToTrim[i] && i != trimlen) || source.Length - start < trimlen)
                            goto DONESTART;
                }
    
            DONESTART:
            if (trimEnd)
                for (int count = 0; end > -1; end -= trimlen, count++)
                {
                    if (numberOfOccurrences != -1 && count == numberOfOccurrences)
                        break;
    
                    for (int i = trimlen - 1; i > -1; --i)
                        if ((source[end - trimlen + i + 1] != whatToTrim[i] && i != 0) || end - start + 1 < trimlen)
                            goto DONEEND;
                }
    
            DONEEND:
            return source.AsSpan().Slice(start, end - start + 1).ToString();
        }
    

提交回复
热议问题