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

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

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


当前回答

以防这里没有足够的答案,这里是我的:)

public static string Truncate(this string str, 
                              int totalLength, 
                              string truncationIndicator = "")
{
    if (string.IsNullOrEmpty(str) || str.Length < totalLength) 
        return str;

    return str.Substring(0, totalLength - truncationIndicator.Length) 
           + truncationIndicator;
}

使用方法:

"I use it like this".Truncate(5,"~")

其他回答

不幸的是,字符串上没有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 TruncateText(string strText, int intLength)
{
    if (!(string.IsNullOrEmpty(strText)))
    {                                
        // split the text.
        var words = strText.Split(' ');

        // calculate the number of words
        // based on the provided characters length 
        // use an average of 7.6 chars per word.
        int wordLength = Convert.ToInt32(Math.Ceiling(intLength / 7.6));

        // if the text is shorter than the length,
        // display the text without changing it.
        if (words.Length <= wordLength)
            return strText.Trim();                

        // put together a shorter text
        // based on the number of words
        return string.Join(" ", words.Take(wordLength)) + " ...".Trim();
    }
        else
        {
            return "";
        }            
    }

我想我应该加入我的实现,因为我相信它涵盖了其他人所涉及的所有情况,并且以一种简洁的方式做到了这一点,仍然是可读的。

public static string Truncate(this string value, int maxLength)
{
    if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
    {
        return value.Substring(0, maxLength);
    }

    return value;
}

该解决方案主要构建在Ray的解决方案之上,并通过使用This关键字将该方法作为扩展方法使用,就像LBushkin在他的解决方案中所做的那样。

基于这个和这个,这里有两个版本,将适用于“到”值的负值。第一个函数不允许负数无声地设置为0:

public static string Truncate(this string value, int maxLength)
{
    return string.IsNullOrEmpty(value) ?
        value :
        value.Substring(0, Math.Max(0, Math.Min(value.Length, maxLength)));
}

这是一个循环:

private static int Mod(this int a, int n) => (((a %= n) < 0) ? n : 0) + a;

public static string Truncate(this string value, int maxLength)
{
    return string.IsNullOrEmpty(value) ?
        value :
        value.Substring(0, maxLength.Mod(value.Length));
}

这是我通常使用的代码:

string getSubString(string value, int index, int length)
        {
            if (string.IsNullOrEmpty(value) || value.Length <= length)
            {
                return value;
            }
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = index; i < length; i++)
            {
                sb.AppendLine(value[i].ToString());
            }
            return sb.ToString();
        }