I\'m looking for String extension methods for TrimStart()
and TrimEnd()
that accept a string parameter.
I could build one myself but I\'m alw
from dotnetperls.com,
Performance
Unfortunately, the TrimStart method is not heavily optimized. In specific situations, you will likely be able to write character-based iteration code that can outperform it. This is because an array must be created to use TrimStart.
However: Custom code would not necessarily require an array. But for quickly-developed applications, the TrimStart method is useful.
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);
}
There is no built in function in C# - but you can write your own extension methods which I will show you below - they can be used like the builtin ones to trim characters, but here you can use strings to trim.
Note that with IndexOf / LastIndexOf, you can choose if it is case sensitive / culture sensitive or not.
I have implemented the feature "repetitive trims" as well (see the optional parameters).
Usage:
var trimmed1 = myStr.TrimStart(trimStr);
var trimmed2 = myStr.TrimEnd(trimStr);
var trimmed3 = myStr.TrimStr(trimStr);
var trimmed4 = myStr.Trim(trimStr);
There is one function TrimStr(..)
trimming from the start and from the end of the string, plus three functions implementing .TrimStart(...)
, .TrimEnd(...)
and .Trim(..)
for compatibility with the .NET trims:
Try it in DotNetFiddle
public static class Extension
{
public static string TrimStr(this string str, string trimStr,
bool trimEnd = true, bool repeatTrim = true,
StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
{
int strLen;
do
{
if (!(str ?? "").EndsWith(trimStr)) return str;
strLen = str.Length;
{
if (trimEnd)
{
var pos = str.LastIndexOf(trimStr, comparisonType);
if ((!(pos >= 0)) || (!(str.Length - trimStr.Length == pos))) break;
str = str.Substring(0, pos);
}
else
{
var pos = str.IndexOf(trimStr, comparisonType);
if (!(pos == 0)) break;
str = str.Substring(trimStr.Length, str.Length - trimStr.Length);
}
}
} while (repeatTrim && strLen > str.Length);
return str;
}
// the following is C#6 syntax, if you're not using C#6 yet
// replace "=> ..." by { return ... }
public static string TrimEnd(this string str, string trimStr,
bool repeatTrim = true,
StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
=> TrimStr(str, trimStr, true, repeatTrim, comparisonType);
public static string TrimStart(this string str, string trimStr,
bool repeatTrim = true,
StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
=> TrimStr(str, trimStr, false, repeatTrim, comparisonType);
public static string Trim(this string str, string trimStr, bool repeatTrim = true,
StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
=> str.TrimStart(trimStr, repeatTrim, comparisonType)
.TrimEnd(trimStr, repeatTrim, comparisonType);
}
Now you can just use it like
Console.WriteLine("Sammy".TrimEnd("my"));
Console.WriteLine("moinmoin gibts gips? gips gibts moin".TrimStart("moin", false));
Console.WriteLine("moinmoin gibts gips? gips gibts moin".Trim("moin").Trim());
which creates the output
Sam
moin gibts gips? gips gibts moin
gibts gips? gips gibts