如何截断.NETstring?

我很抱歉可能有一个微不足道的解决scheme,但奇怪的是,我找不到这个问题简洁的API。

本质上,我想截断一个string,使其长度不超过一个给定的值。 我正在写数据库表,并希望确保我写的值符合列的数据types的约束。

例如,如果我可以写下以下代码将会很好:

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

不幸的是,这会引发一个exception,因为maxLength通常超出了stringvalue的边界。 当然,我可以写如下的函数,但是我希望这样的东西已经存在了。

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

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

不幸的是,string中没有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); 

或者,而不是三元运算符,你可以使用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)); } } 

我想我会抛出我的实现,因为我认为它涵盖了所有被其他人触及的情况,并且以简洁明了的方式仍然可读。

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

这个解决scheme主要build立在Ray的解决scheme上,并且像LBushkin在他的解决scheme中那样使用这个关键字来打开用作扩展方法的方法。

你可以使用LINQ …它消除了检查string长度的需要。 诚然,也许不是最有效的,但它很有趣。

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

要么

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

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

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

没有testing效率!

.NET Framework有一个API来截断string,如下所示:

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

但是在C#应用程序中,您可能更愿意推出自己的产品,而不是依赖Microsoft.VisualBasic.dll,其主要理由是向后兼容。

似乎还没有人发布这个呢:

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

使用&&运算符使其稍好于接受的答案。

因为性能testing很有趣:(使用linqpad扩展方法 )

 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方法“显着”更快。 #microoptimization

  • truncate10 5788个滴答消耗(0.5788 ms)[在10K代表中,5.788E-05 ms每个]
  • smart-trunc10 8206滴答已过(0.8206 ms)[在10K代表中,8.206E-05 ms每个]
  • stringbuilder10 10557滴答时间(1.0557毫秒)[在10K代表,0.00010557毫秒每]
  • concat10已经过45495个滴答(4.5495 ms)[10K代表,0.00045495 ms每个]
  • newstring10 72535滴答已过(7.2535毫秒)[10K代表,0.00072535毫秒每]

晚了

  • truncate44 8835滴答时间(0.8835 ms)[在10K代表中,8.835E-05 ms每个]
  • stringbuilder44 13106滴答已过(1.3106毫秒)[10K代表,0.00013106毫秒每]
  • smart-trunc44 14821滴答已过(1.4821毫秒)[10K代表,0.00014821毫秒每]
  • newstring44 144324滴答已过(14.4324毫秒)[在10K代表,0.00144324毫秒每]
  • concat44 174610滴答已用(17.461毫秒)[10K代表,0.0017461毫秒每]

太长

  • smart-trunc64 6944滴答时间(0.6944 ms)[在10K代表中,6.944E-05 ms每个]
  • 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毫秒每]

为什么不

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

即事件value.Length <maxLength填充空格到结束或截断多余。

以@CaffGeek并简化它:

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

Kndly指出,截断一个string不仅意味着仅仅按照指定的长度切割一个string,而且必须注意不要分割字。

例如string:这是一个testingstring。

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

这是一个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()); } 

与C#6的空传播运算符类似的变体

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

请注意,我们实质上是在这里检查两次value是否为空。

我是这样做的

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

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

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

退货:你好…

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

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

为了复杂性,我将添加我的重载版本,用maxLength参数中的省略号replace最后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)); } 

对于C#string,2016年仍然没有截断方法。 但是 – 使用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" 

我更喜欢jpierson的答案,但是我可以看到这里没有任何例子是处理一个无效的maxLength参数,比如当maxLength <0时。

select将处理try / catch中的错误,将maxLength参数min限制为0,或者如果maxLength小于0,则返回空string。

未优化的代码:

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

这里是一个vb.net解决scheme,标记if(虽然丑)语句提高性能,因为当string已经小于maxlength时,我们不需要substring语句…通过扩展string,它很容易使用。 ..

  <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 

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

我知道已经有很多答案了,但是我的需要是保持string的开始和结束,但是将其缩短到最大长度。

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

这用于创build最大长度为260个字符的SharePoint URL。

我没有把长度作为一个参数,因为它是一个常数260.我也没有把第一个子string长度作为一个参数,因为我想让它在特定的点上断开。 最后,第二个子string是源文件的长度 – 20,因为我知道文件夹结构。

这可以很容易地适应您的具体需求。

在.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; } } 
 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 } 

截断string

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

这是我通常使用的代码:

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