Усечь строку на целые слова in.NET C#
Я пытаюсь усечь какой-то длинный текст в C#, но я не хочу, чтобы моя строка была отрезана частично через слово. У кого-нибудь есть функция, которую я могу использовать для усечения моей строки в конце слова?
например:
"This was a long string..."
нет:
"This was a long st..."
9 ответов:
попробуйте следующее. Это довольно простое. Просто находит первое пространство, начиная с нужной длины.
public static string TruncateAtWord(this string value, int length) { if (value == null || value.Length < length || value.IndexOf(" ", length) == -1) return value; return value.Substring(0, value.IndexOf(" ", length)); }
Спасибо за ваш ответ Дэйв. Я немного изменил функцию, и это то, что я использую ... если нет больше комментариев ;)
public static string TruncateAtWord(this string input, int length) { if (input == null || input.Length < length) return input; int iNextSpace = input.LastIndexOf(" ", length, StringComparison.Ordinal); return string.Format("{0}...", input.Substring(0, (iNextSpace > 0) ? iNextSpace : length).Trim()); }
мой вклад:
public static string TruncateAtWord(string text, int maxCharacters, string trailingStringIfTextCut = "…") { if (text == null || (text = text.Trim()).Length <= maxCharacters) return text; int trailLength = trailingStringIfTextCut.StartsWith("&") ? 1 : trailingStringIfTextCut.Length; maxCharacters = maxCharacters - trailLength >= 0 ? maxCharacters - trailLength : 0; int pos = text.LastIndexOf(" ", maxCharacters); if (pos >= 0) return text.Substring(0, pos) + trailingStringIfTextCut; return string.Empty; }
Это то, что я использую в своих проектах, с дополнительным трейлингом. Текст никогда не будет превышать maxCharacters + конечная длина текста.
Если вы используете windows forms, в графике.DrawString метод, есть опция в StringFormat, чтобы указать, если строка должна быть усечена, если она не вписывается в указанную область. Это будет обрабатывать добавление многоточия по мере необходимости.
http://msdn.microsoft.com/en-us/library/system.drawing.stringtrimming.aspx
Это решение тоже работает (берет первые 10 слов из myString):
String.Join(" ", myString.Split(' ').Take(10))
Я взял ваш подход несколько дальше:
public string TruncateAtWord(string value, int length) { if (value == null || value.Trim().Length <= length) return value; int index = value.Trim().LastIndexOf(" "); while ((index + 3) > length) index = value.Substring(0, index).Trim().LastIndexOf(" "); if (index > 0) return value.Substring(0, index) + "..."; return value.Substring(0, length - 3) + "..."; }
Я использую это для усечения твитов.
упрощенный, добавлена опция транкинг символ и сделал его расширение.
public static string TruncateAtWord(this string value, int maxLength) { if (value == null || value.Trim().Length <= maxLength) return value; string ellipse = "..."; char[] truncateChars = new char[] { ' ', ',' }; int index = value.Trim().LastIndexOfAny(truncateChars); while ((index + ellipse.Length) > maxLength) index = value.Substring(0, index).Trim().LastIndexOfAny(truncateChars); if (index > 0) return value.Substring(0, index) + ellipse; return value.Substring(0, maxLength - ellipse.Length) + ellipse; }
вот что я придумал. Это должно получить остальную часть предложения также кусками.
public static List<string> SplitTheSentenceAtWord(this string originalString, int length) { try { List<string> truncatedStrings = new List<string>(); if (originalString == null || originalString.Trim().Length <= length) { truncatedStrings.Add(originalString); return truncatedStrings; } int index = originalString.Trim().LastIndexOf(" "); while ((index + 3) > length) index = originalString.Substring(0, index).Trim().LastIndexOf(" "); if (index > 0) { string retValue = originalString.Substring(0, index) + "..."; truncatedStrings.Add(retValue); string shortWord2 = originalString; if (retValue.EndsWith("...")) { shortWord2 = retValue.Replace("...", ""); } shortWord2 = originalString.Substring(shortWord2.Length); if (shortWord2.Length > length) //truncate it further { List<string> retValues = SplitTheSentenceAtWord(shortWord2.TrimStart(), length); truncatedStrings.AddRange(retValues); } else { truncatedStrings.Add(shortWord2.TrimStart()); } return truncatedStrings; } var retVal_Last = originalString.Substring(0, length - 3); truncatedStrings.Add(retVal_Last + "..."); if (originalString.Length > length)//truncate it further { string shortWord3 = originalString; if (originalString.EndsWith("...")) { shortWord3 = originalString.Replace("...", ""); } shortWord3 = originalString.Substring(retVal_Last.Length); List<string> retValues = SplitTheSentenceAtWord(shortWord3.TrimStart(), length); truncatedStrings.AddRange(retValues); } else { truncatedStrings.Add(retVal_Last + "..."); } return truncatedStrings; } catch { return new List<string> { originalString }; } }