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

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

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


当前回答

我建议使用substring方法来实现同样有效的功能。

    // Gets first n characters.
    string subString = inputString.Substring(0, n);

这样做的好处是,您可以从任意一侧甚至中间的某个地方拼接字符串,而无需编写额外的方法。希望这对你有所帮助。

更多参考:https://www.dotnetperls.com/substring

其他回答

所有其他答案都没有考虑到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:

更少的分配。 更少的分配时间。 使代码总体上更快地使用。

我的观点是,例子长度为30:

  var truncatedInput = string.IsNullOrEmpty(input) ? 
      string.Empty : 
      input.Substring(0, Math.Min(input.Length, 30));

请注意,截断字符串不仅仅意味着仅以指定的长度切割字符串,而且必须注意不要分割单词。

Eg字符串:这是一个测试字符串。

我想把它剪到11点。如果我们使用上面给出的任何一种方法,结果将是

这是一个

这不是我们想要的

我使用的方法可能也不是那么完美,但它可以处理大多数情况

public string CutString(string source, int length)
{
        if (source== null || source.Length < length)
        {
            return source;
        }
        int nextSpace = source.LastIndexOf(" ", length);
        return string.Format("{0}...", input.Substring(0, (nextSpace > 0) ? nextSpace : length).Trim());
} 
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
    }

TruncateString

public static string _TruncateString(string input, int charaterlimit)
{
    int characterLimit = charaterlimit;
    string output = input;

    // Check if the string is longer than the allowed amount
    // otherwise do nothing
    if (output.Length > characterLimit && characterLimit > 0)
    {
        // cut the string down to the maximum number of characters
        output = output.Substring(0, characterLimit);
        // Check if the character right after the truncate point was a space
        // if not, we are in the middle of a word and need to remove the rest of it
        if (input.Substring(output.Length, 1) != " ")
        {
            int LastSpace = output.LastIndexOf(" ");

            // if we found a space then, cut back to that space
            if (LastSpace != -1)
            {
                output = output.Substring(0, LastSpace);
            }
        }
        // Finally, add the "..."
        output += "...";
    }
    return output;
}