我想截断一个字符串,使其长度不超过给定值。我正在向数据库表写入数据,并希望确保写入的值满足列数据类型的约束。

例如,如果我能写以下内容,那就太好了:

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在哪里?有吗?


当前回答

出于(过度)复杂性的考虑,我将添加重载版本,它将maxLength参数的最后3个字符替换为省略号。

public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
    if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
        throw new ArgumentOutOfRangeException("maxLength",
            "maxLength should be greater than three when replacing with an ellipsis.");

    if (String.IsNullOrWhiteSpace(value)) 
        return String.Empty;

    if (replaceTruncatedCharWithEllipsis &&
        value.Length > maxLength)
    {
        return value.Substring(0, maxLength - 3) + "...";
    }

    return value.Substring(0, Math.Min(value.Length, maxLength)); 
}

其他回答

public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return new string(value.Take(maxLength).ToArray());// use LINQ and be happy
    }

我更喜欢jpierson的答案,但我在这里看到的示例都没有处理无效的maxLength参数,例如当maxLength < 0时。

可以选择在try/catch中处理错误,将maxLength参数min限制为0,或者如果maxLength小于0则返回空字符串。

未优化的代码:

public string Truncate(this string value, int maximumLength)
{
    if (string.IsNullOrEmpty(value) == true) { return value; }
    if (maximumLen < 0) { return String.Empty; }
    if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
    return value;
}

作为上述可能性的补充,我想分享一下我的解决方案。 它是一个扩展方法,允许null(返回string.Empty),还有第二个. truncate()用于与省略号一起使用。注意,它不是性能优化的。

public static string Truncate(this string value, int maxLength) =>
    (value ?? string.Empty).Substring(0, (value?.Length ?? 0) <= (maxLength < 0 ? 0 : maxLength) ? (value?.Length ?? 0) : (maxLength < 0 ? 0 : maxLength));
public static string Truncate(this string value, int maxLength, string ellipsis) =>
    string.Concat(value.Truncate(maxLength - (((value?.Length ?? 0) > maxLength ? ellipsis : null)?.Length ?? 0)), ((value?.Length ?? 0) > maxLength ? ellipsis : null)).Truncate(maxLength);

在c# 8中,新的范围特性可以被使用…

value = value[..Math.Min(30, value.Length)];

出于(过度)复杂性的考虑,我将添加重载版本,它将maxLength参数的最后3个字符替换为省略号。

public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
    if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
        throw new ArgumentOutOfRangeException("maxLength",
            "maxLength should be greater than three when replacing with an ellipsis.");

    if (String.IsNullOrWhiteSpace(value)) 
        return String.Empty;

    if (replaceTruncatedCharWithEllipsis &&
        value.Length > maxLength)
    {
        return value.Substring(0, maxLength - 3) + "...";
    }

    return value.Substring(0, Math.Min(value.Length, maxLength)); 
}