I am trying to truncate some long text in C#, but I don\'t want my string to be cut off part way through a word. Does anyone have a function that I can use to truncate my st
Taking into account more than just a blank space separator (e.g. words can be separated by periods followed by newlines, followed by tabs, etc.), and several other edge cases, here is an appropriate extension method:
public static string GetMaxWords(this string input, int maxWords, string truncateWith = "...", string additionalSeparators = ",-_:")
{
int words = 1;
bool IsSeparator(char c) => Char.IsSeparator(c) || additionalSeparators.Contains(c);
IEnumerable<char> IterateChars()
{
yield return input[0];
for (int i = 1; i < input.Length; i++)
{
if (IsSeparator(input[i]) && !IsSeparator(input[i - 1]))
if (words == maxWords)
{
foreach (char c in truncateWith)
yield return c;
break;
}
else
words++;
yield return input[i];
}
}
return !input.IsNullOrEmpty()
? new String(IterateChars().ToArray())
: String.Empty;
}
simplified, added trunking character option and made it an extension.
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;
}
This solution works too (takes first 10 words from myString):
String.Join(" ", myString.Split(' ').Take(10))
My contribution:
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;
}
This is what I use in my projects, with optional trailing. Text will never exceed the maxCharacters + trailing text length.