首页 文章

如何截断.NET字符串?

提问于
浏览
332

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

例如,如果我能写下面的内容会很好:

string NormalizeLength(string value, int maxLength)
{
    return value.Substring(0, maxLength);
}

不幸的是,这引发了异常,因为 maxLength 通常超出了字符串 value 的边界 . 当然,我可以编写如下的函数,但我希望这样的东西已经存在 .

string NormalizeLength(string value, int maxLength)
{
    return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}

执行此任务的难以捉摸的API在哪里?有吗?

28 回答

  • 2

    这是我经常使用的代码:

    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();
            }
    
  • 502

    There isn't a Truncate() method on string, unfortunately. 你必须自己写这种逻辑 . 但是,你可以做的是将它包装在扩展方法中,这样你就不必在任何地方复制它:

    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);
    
  • 16

    或者代替三元运算符,您可以使用Math.min

    public static class StringExt
    {
        public static string Truncate( this string value, int maxLength )
        {
            if (string.IsNullOrEmpty(value)) { return value; }
    
            return value.Substring(0, Math.Min(value.Length, maxLength));
        }
    }
    
  • 12

    我想我会抛弃我的实现,因为我相信它涵盖了其他人已经触及的所有案例,并且以简洁的方式这样做仍然可读 .

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

    这个解决方案主要 Build 在Ray's solution之上,并通过在他的解决方案中使用this关键字LBushkin does打开了用作扩展方法的方法 .

  • -1

    您可以使用LINQ ...它消除了检查字符串长度的需要 . 不可否认,也许不是最有效的,但它很有趣 .

    string result = string.Join("", value.Take(maxLength)); // .NET 4 Join
    

    要么

    string result = new string(value.Take(maxLength).ToArray());
    
  • 4

    在.NET 4.0中,您可以使用 Take 方法:

    string.Concat(myString.Take(maxLength));
    

    没有测试效率!

  • 4

    因为性能测试很有趣:(使用linqpad extension methods

    var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));
    
    foreach(var limit in new[] { 10, 25, 44, 64 })
        new Perf<string> {
            { "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
            { "concat" + limit, n => string.Concat(val.Take(limit)) },
            { "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
            { "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
            { "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
        }.Vs();
    

    truncate 方法更快"significantly" . #microoptimization

    truncate10 5788 ticks过去了(0.5788 ms)[10K reps,5.788E-05 ms per] smart-trunc10 8206 ticks过去了(0.8206 ms)[10K reps,8.206E-05 ms per] stringbuilder10 10557 ticks过去了(1.0557 ms )[在10K代表中,每个0.00010557毫秒] concat10 45495经过时间(4.5495毫秒)[在10K代表中,每天0.00045495毫秒] newstring10 72535时间流逝(7.2535毫秒)[在10K代表中,每个0.00072535毫秒]

    晚了

    truncate44 8835 ticks过去了(0.8835 ms)[10K reps,8.835E-05 ms per] stringbuilder44 13106 ticks elapsed(1.3106 ms)[in 10K reps,0.00013106 ms per] smart-trunc44 14821 ticks elapsed(1.4821 ms)[in 10K reps,0.00014821 ms per] newstring44 144324 ticks elapsed(14.4324 ms)[in 10K reps,0.00144324 ms per] concat44 174610 ticks elapsed(17.461 ms)[in 10K reps,0.0017461 ms per]

    太长

    smart-trunc64 6944刻度已过去(0.6944 ms)[以10K代表,每天6.944E-05毫秒] truncate64经过7686个刻度(0.7686毫秒)[在10K代表中,每个7.686E-05毫秒] stringbuilder64 13314刻度已过去(1.3314毫秒) )[在10K代表,每个0.00013314毫秒] newstring64 177481经过时间(17.7481毫秒)[在10K代表中,每个0.00177481毫秒] concat64 241601经过时间(24.1601毫秒)[在10K代表中,每个0.00241601毫秒]

  • 1

    .NET Framework有一个API来截断这样的字符串:

    Microsoft.VisualBasic.Strings.Left(string, int);
    

    但是在C#应用程序中,你可能更喜欢自己动手而不是依赖于Microsoft.VisualBasic.dll,它的主要存在是向后兼容性 .

  • -1

    似乎还没有人发布这个:

    public static class StringExt
    {
        public static string Truncate(this string s, int maxLength)
        {
            return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
        }
    }
    

    使用&&运算符使其略微优于接受的答案 .

  • 0

    我在一条线上做了这样的事情

    value = value.Length > 1000 ? value.Substring(0, 1000) : value;
    
  • 1

    与C#6的Null传播算子类似的变体

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

    请注意,我们基本上检查 value 在此处是否为空两次 .

  • 0

    以@CaffGeek为例,简化它:

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

    Kndly注意到截断字符串不仅仅意味着仅仅按指定长度剪切字符串,而是必须注意不要分割字 .

    例如string:这是一个测试字符串 .

    我想在11点削减它 . 如果我们使用上面给出的任何方法,结果将是

    this is a te

    这不是我们想要的

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

    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());
    }
    
  • 26

    我知道这是一个老问题,但这是一个很好的解决方案:

    public static string Truncate(this string text, int maxLength, string suffix = "...")
    {
        string str = text;
        if (maxLength > 0)
        {
            int length = maxLength - suffix.Length;
            if (length <= 0)
            {
                return str;
            }
            if ((text != null) && (text.Length > maxLength))
            {
                return (text.Substring(0, length).TrimEnd(new char[0]) + suffix);
            }
        }
        return str;
    }
    
    var myString = "hello world"
    var myTruncatedString = myString.Truncate(4);
    

    返回:你好......

  • 10

    2016年C#字符串仍然没有Truncate方法 . 但是 - 使用C#6.0语法:

    public static class StringExtension
    {
      public static string Truncate(this string s, int max) 
      { 
        return s?.Length > max ? s.Substring(0, max) : s ?? throw new ArgumentNullException(s); 
      }
    }
    

    它就像一个魅力:

    "Truncate me".Truncate(8);
    Result: "Truncate"
    
  • 5

    万一这里的答案不够,这里是我的:)

    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,"~")
    
  • -4

    为什么不:

    string NormalizeLength(string value, int maxLength)
    {
        //check String.IsNullOrEmpty(value) and act on it. 
        return value.PadRight(maxLength).Substring(0, maxLength);
    }
    

    即在事件 value.Length < maxLength 垫空间到最后或截断多余 .

  • 8

    为了(过度)复杂性,我将添加我的重载版本,该版本用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)); 
    }
    
  • -3

    我更喜欢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;
    }
    
  • 4

    这里有一个vb.net解决方案,标记if(虽然丑陋)语句提高了性能,因为当string已经小于maxlength时我们不需要substring语句...通过使它成为字符串的扩展它很容易使用...

    <System.Runtime.CompilerServices.Extension()> _
        Public Function Truncate(String__1 As String, maxlength As Integer) As String
            If Not String.IsNullOrEmpty(String__1) AndAlso String__1.Length > maxlength Then
                Return String__1.Substring(0, maxlength)
            Else
                Return String__1
            End If
        End Function
    
  • 34

    我知道已经有很多答案,但我的需要是保持字符串的开头和结尾完整但缩短到最大长度 .

    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,因为我知道文件夹结构 .

    这可以很容易地适应您的特定需求 .

  • 4

    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;
    }
    
  • 103

    我知道这里已经有很多答案了,但这是我用过的那个,它处理空字符串和传入的长度为负的情况:

    public static string Truncate(this string s, int length)
    {
        return string.IsNullOrEmpty(s) || s.Length <= length ? s 
            : length <= 0 ? string.Empty 
            : s.Substring(0, length);
    }
    
  • -1

    作为上述讨论的可能性的补充,我想分享我的解决方案 . 它是一个允许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);
    
  • 0

    在我所知道的.net中没有任何内容 - 这是我的版本添加了“......”:

    public static string truncateString(string originalString, int length) {
      if (string.IsNullOrEmpty(originalString)) {
       return originalString;
      }
      if (originalString.Length > length) {
       return originalString.Substring(0, length) + "...";
      }
      else {
       return originalString;
      }
    }
    
  • 1
    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
        }
    
  • 3

    我建议使用substring方法获得相同的有效功能 .

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

    这样做的好处是可以让你从任何一边或甚至中间的某个地方拼接你的字符串,而无需编写其他方法 . 希望有所帮助:)

    供其他参考:https://www.dotnetperls.com/substring

  • 3

    截断字符串

    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 "";
            }            
        }
    

相关问题