我想截断一个字符串,使其长度不超过给定值。我正在向数据库表写入数据,并希望确保写入的值满足列数据类型的约束。
例如,如果我能写以下内容,那就太好了:
string NormalizeLength(string value, int maxLength)
{
return value.Substring(0, maxLength);
}
不幸的是,这会引发异常,因为maxLength通常超过字符串值的边界。当然,我可以写一个像下面这样的函数,但我希望这样的东西已经存在了。
string NormalizeLength(string value, int maxLength)
{
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
执行此任务的难以捉摸的API在哪里?有吗?
所有其他答案都没有考虑到Span的性能,它比。net中字符串类型的Substring的性能更好
如果你还不知道有一个版本的系统。内存(为以下情况提供了Span, ReadOnlySpan, Memory和ReadOnlyMemory:
这样的简单实现可以如下所示:
public static string Truncate(this string value, int maxLength)
{
if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
{
return value.AsSpan(0, maxLength).ToString(); /* Note the use of AsSpan instead of Substring. */
}
return value;
}
该方法理论上可以返回Span<char>,以避免使用Span<T>的ToString()成员分配新字符串。
The BCL itself internally uses Span's, ReadOnlySpan's, Memory's, and ReadOnlyMemory's where possible to avoid issues and to help optimize the code, especially when you compile arrays that are known at compile time and so using an property that returns that new'd up array as an ReadOnlySpan<byte> actually optimizes the code at runtime as then the JIT would not call memcpy on the data and instead uses it since it just returns a Span and as such is a window to the data that is already allocated ahead of time resulting in:
更少的分配。
更少的分配时间。
使代码总体上更快地使用。
不幸的是,字符串上没有Truncate()方法。你必须自己写出这种逻辑。然而,你能做的是把它包装在一个扩展方法中,这样你就不必到处复制它:
public static class StringExt
{
public static string Truncate(this string value, int maxLength)
{
if (string.IsNullOrEmpty(value)) return value;
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
}
现在我们可以这样写:
var someString = "...";
someString = someString.Truncate(2);
可选的后缀和c#8可空引用类型。
public static class StringExt
{
public static string? Truncate(this string? value, int maxLength, string truncationSuffix = "…")
{
return value?.Length > maxLength
? value.Substring(0, maxLength) + truncationSuffix
: value;
}
}
写:
"abc".Truncate(2); // "ab…"
"abc".Truncate(3); // "abc"
((string)null).Truncate(3); // null
我知道已经有大量的答案,但我的需要是保持字符串的开始和结束完整,但缩短到最大长度以下。
public static string TruncateMiddle(string source)
{
if (String.IsNullOrWhiteSpace(source) || source.Length < 260)
return source;
return string.Format("{0}...{1}",
source.Substring(0, 235),
source.Substring(source.Length - 20));
}
用于创建最大长度为260个字符的SharePoint url。
我没有把长度作为参数,因为它是一个常数260。我也没有将第一个子字符串长度作为参数,因为我希望它在特定的点中断。最后,第二个子字符串是源文件的长度——20,因为我知道文件夹的结构。
这可以很容易地适应您的特定需求。