C# TrimStart with string parameter

I'm looking for String extension methods for TrimStart() and TrimEnd() that accept a string parameter.

I could build one myself but I'm always interested in seeing how other people do things.

How can this be done?


To trim all occurrences of the (exactly matching) string, you can use something like the following:

TrimStart

public static string TrimStart(this string target, string trimString)
{
    if (string.IsNullOrEmpty(trimString)) return target;

    string result = target;
    while (result.StartsWith(trimString))
    {
        result = result.Substring(trimString.Length);
    }

    return result;
}

TrimEnd

public static string TrimEnd(this string target, string trimString)
{
    if (string.IsNullOrEmpty(trimString)) return target;

    string result = target;
    while (result.EndsWith(trimString))
    {
        result = result.Substring(0, result.Length - trimString.Length);
    }

    return result;
}

To trim any of the characters in trimChars from the start/end of target (e.g. "foobar'@"@';".TrimEnd(";@'") will return "foobar") you can use the following:

TrimStart

public static string TrimStart(this string target, string trimChars)
{
    return target.TrimStart(trimChars.ToCharArray());
}

TrimEnd

public static string TrimEnd(this string target, string trimChars)
{
    return target.TrimEnd(trimChars.ToCharArray());
}

TrimStart and TrimEnd takes in an array of chars. This means that you can pass in a string as a char array like this:

var trimChars = " .+-";
var trimmed = myString.TrimStart(trimChars.ToCharArray());

So I don't see the need for an overload that takes a string parameter.


I thought the question was trying to trim a specific string from the start of a larger string.

For instance, if I had the string "hellohellogoodbyehello", if you tried to call TrimStart("hello") you would get back "goodbyehello".

If that is the case, you could use code like the following:

string TrimStart(string source, string toTrim)
{
    string s = source;
    while (s.StartsWith(toTrim))
    {
        s = s.Substring(toTrim.Length - 1);
    }
    return s;
}

This wouldn't be super-efficient if you needed to do a lot of string-trimming, but if its just for a few cases, it is simple and gets the job done.


To match entire string and not allocate multiple substrings, you should use the following:

    public static string TrimStart(this string source, string value, StringComparison comparisonType)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        int valueLength = value.Length;
        int startIndex = 0;
        while (source.IndexOf(value, startIndex, comparisonType) == startIndex)
        {
            startIndex += valueLength;
        }

        return source.Substring(startIndex);
    }

    public static string TrimEnd(this string source, string value, StringComparison comparisonType)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        int sourceLength = source.Length;
        int valueLength = value.Length;
        int count = sourceLength;
        while (source.LastIndexOf(value, count, comparisonType) == count - valueLength)
        {
            count -= valueLength;
        }

        return source.Substring(0, count);
    }