我正在寻找接受字符串参数的TrimStart()
和TrimEnd()
的字符串扩展方法。
我自己可以建立一个,但我总是对看别人如何做事感兴趣。
如何做到这一点?
答案 0 :(得分:82)
要修剪所有出现的(完全匹配的)字符串,您可以使用以下内容:
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;
}
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;
}
要从目标的开头/结尾修剪trimChars中的任何字符(例如"foobar'@"@';".TrimEnd(";@'")
将返回"foobar"
),您可以使用以下内容:
public static string TrimStart(this string target, string trimChars)
{
return target.TrimStart(trimChars.ToCharArray());
}
public static string TrimEnd(this string target, string trimChars)
{
return target.TrimEnd(trimChars.ToCharArray());
}
答案 1 :(得分:14)
TrimStart和TrimEnd接收一组字符。这意味着您可以将字符串作为char数组传递,如下所示:
var trimChars = " .+-";
var trimmed = myString.TrimStart(trimChars.ToCharArray());
所以我认为不需要带有字符串参数的重载。
答案 2 :(得分:12)
我认为问题是尝试从较大字符串的开头修剪特定字符串。
例如,如果我有字符串" hellohellogoodbyehello",如果你试图调用TrimStart("你好"),你会回来" goodbyehello"。 / p>
如果是这种情况,您可以使用以下代码:
string TrimStart(string source, string toTrim)
{
string s = source;
while (s.StartsWith(toTrim))
{
s = s.Substring(toTrim.Length - 1);
}
return s;
}
如果您需要进行大量的字符串修剪,这不会超级高效,但如果仅仅针对少数情况,则很简单并完成工作。
答案 3 :(得分:4)
要匹配整个字符串而不分配多个子字符串,您应该使用以下内容:
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);
}
答案 4 :(得分:3)
性能
不幸的是,TrimStart方法没有经过大量优化。在 具体情况,你很可能会写出基于字符的 迭代代码,可以超越它。这是因为数组必须 创建使用TrimStart。
但是:自定义代码不一定需要数组。但对于 快速开发的应用程序,TrimStart方法很有用。
答案 5 :(得分:0)
C#中没有内置函数 - 但您可以编写自己的扩展,其行为与您期望的完全相同。
请注意,使用IndexOf / LastIndexOf,您可以选择是否区分大小写/区分大小写。
我也实现了“重复修剪”功能。
有一个函数TrimStr(..)
处理这两个修剪,加上三个实现.TrimStart(...)
,.TrimEnd(...)
和.Trim(..)
的函数与.NET修剪兼容:
<强> 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);
}
现在你可以像
一样使用它 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());
创建输出
山姆郎 moin gibts gips? gips gibts moin
gibts gips? gips gibts
答案 6 :(得分:-1)
我假设你的意思是,例如,给定字符串“HelloWorld”并调用函数“修剪”开头的“Hello”,你将留下“World”。我认为这实际上是一个子字符串操作,因为你要删除已知长度的字符串的一部分,而不是删除未知长度的字符串的修剪操作。
因此,我们创建了一些名为SubstringAfter
和SubstringBefore
的扩展方法。将它们放在框架中会很好,但它们并非如此,您需要自己实现它们。不要忘记拥有StringComparison
参数,并且如果您将其设为可选项,则使用Ordinal
作为默认值。
答案 7 :(得分:-1)
如果您确实想要一个不使用内置修剪函数的原因,假设您想要一个输入字符串用于修剪,例如“〜!”基本上与内置的TrimStart相同['','〜','!']
public static String TrimStart(this string inp, string chars)
{
while(chars.Contains(inp[0]))
{
inp = inp.Substring(1);
}
return inp;
}
public static String TrimEnd(this string inp, string chars)
{
while (chars.Contains(inp[inp.Length-1]))
{
inp = inp.Substring(0, inp.Length-1);
}
return inp;
}
答案 8 :(得分:-1)
使用字符串参数修剪字符串的开始/结束的函数,但是仅一次(不循环,这种情况更常见,可以添加循环并添加额外的参数来触发它):
public static class BasicStringExtensions
{
public static string TrimStartString(this string str, string trimValue)
{
if (str.StartsWith(trimValue))
return str.TrimStart(trimValue.ToCharArray());
//otherwise don't modify
return str;
}
public static string TrimEndString(this string str, string trimValue)
{
if (str.EndsWith(trimValue))
return str.TrimEnd(trimValue.ToCharArray());
//otherwise don't modify
return str;
}
}
如前所述,如果要实现“ while循环”方法,请确保检查空字符串,否则它将永远循环。