如何截断.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(); }