[c#] How do I truncate a .NET string?

I would like to truncate a string such that its length is not longer than a given value. I am writing to a database table and want to ensure that the values I write meet the constraint of the column's datatype.

For instance, it would be nice if I could write the following:

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

Unfortunately, this raises an exception because maxLength generally exceeds the boundaries of the string value. Of course, I could write a function like the following, but I was hoping that something like this already exists.

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

Where is the elusive API that performs this task? Is there one?

This question is related to c# .net string truncate

The answer is


For the sake of (over)complexity I'll add my overloaded version which replaces the last 3 characters with an ellipsis in respect with the maxLength parameter.

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

Another solution:

return input.Substring(0, Math.Min(input.Length, maxLength));

I'd Recommend using the substring method for the same effective functionality.

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

This has the benefit of letting you splice your string from either side or even somewhere in the middle without writing additional methods. Hope that helps :)

For additional reference: https://www.dotnetperls.com/substring


Because performance testing is fun: (using 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();

The truncate method was "significantly" faster. #microoptimization

Early

  • truncate10 5788 ticks elapsed (0.5788 ms) [in 10K reps, 5.788E-05 ms per]
  • smart-trunc10 8206 ticks elapsed (0.8206 ms) [in 10K reps, 8.206E-05 ms per]
  • stringbuilder10 10557 ticks elapsed (1.0557 ms) [in 10K reps, 0.00010557 ms per]
  • concat10 45495 ticks elapsed (4.5495 ms) [in 10K reps, 0.00045495 ms per]
  • newstring10 72535 ticks elapsed (7.2535 ms) [in 10K reps, 0.00072535 ms per]

Late

  • truncate44 8835 ticks elapsed (0.8835 ms) [in 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]

Too Long

  • smart-trunc64 6944 ticks elapsed (0.6944 ms) [in 10K reps, 6.944E-05 ms per]
  • truncate64 7686 ticks elapsed (0.7686 ms) [in 10K reps, 7.686E-05 ms per]
  • stringbuilder64 13314 ticks elapsed (1.3314 ms) [in 10K reps, 0.00013314 ms per]
  • newstring64 177481 ticks elapsed (17.7481 ms) [in 10K reps, 0.00177481 ms per]
  • concat64 241601 ticks elapsed (24.1601 ms) [in 10K reps, 0.00241601 ms per]

Based on this, and this, here are two versions that will work for negative values of 'up to' values as well. This first one doesn't allow negative values silently by capping at 0:

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

This one goes in circle:

private static int Mod(this int a, int n) => (((a %= n) < 0) ? n : 0) + a;

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

I know there are a ton of answers already but my need was to keep the beginning and end of the string intact but shorten it to under the max length.

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

This is for creating SharePoint URLs that have a max length of 260 characters.

I didn't make length a parameter since it is a constant 260. I also didn't make the first substring length a parameter because I want it to break at a specific point. Finally, the second substring is the length of the source - 20 since I know the folder structure.

This could easily be adapted to your specific needs.


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

I know there are a ton of answers here already, but this is the one I have gone with, which handles both null strings and the situation where the length passed in is negative:

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

You could use LINQ... it eliminates the need to check string length. Admittedly maybe not the most efficient, but it's fun.

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

or

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

The simplest method in recent C# would be:

string Trunc(string s, int len) => s?.Length > len ? s.Substring(0, len) : s;

It returns truncated value for longer strings and original string for other cases - including null input - which is treated by ? unary operator.


This is the code I usually use:

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

Kndly note that truncating a string not merely means justing cutting a string at a specified length alone but have to take care not to split the word.

eg string : this is a test string.

I want to cut it at 11 . If we use any of the method given above the result will be

this is a te

This is not the thing we want

The method i am using may also not so perfect but it can handle most of the situation

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

In .NET 4.0 you can use the Take method:

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

Not tested for efficiency!


Why not:

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

i.e. in the event value.Length < maxLength pad spaces to the end or truncate the excess.


A similar variant with C# 6's Null propagation operator

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

Please note, we are essentially checking if value is null twice here.


I know this is an old question, but here is a nice solution:

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

Returns: hello...


Here is a vb.net solution, mark that the if (although ugly) statement improves performance because we do not need the substring statement when string is already smaller than maxlength... By making it an extention to string it is easy to use...

 <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

Taking @CaffGeek and simplifying it:

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

Or instead of the ternary operator, you could use 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));
    }
}

The .NET Framework has an API to truncate a string like this:

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

But in a C# app you'll probably prefer to roll your own than taking a dependency on Microsoft.VisualBasic.dll, whose main raison d'etre is backwards compatibility.


As an addition to the possibilities discussed above I'd like to share my solution. It's an extension method that allows null (returns string.Empty) also there is a second .Truncate() for using it with an ellipsis. Beware, it's not performance optimized.

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

I did mine in one line sort of like this

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

I figured I would throw in my implementation since I believe it covers all of the cases that have been touched on by the others and does so in a concise way that is still readable.

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

    return value;
}

This solution mainly builds upon the Ray's solution and opens up the method for use as an extension method by using the this keyword just as LBushkin does in his solution.


You can create a Truncate extension method that compares the max length relative to the string length and calls Substring if needed.

If you want null handling behavior that parallels that of Substring, don't include a null check. That way, just as str.Substring(0, 10) throws a NullReferenceException if str is null, so will str.Truncate(10).

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

In C# 8 the new Ranges feature can be used...

value = value[..Math.Min(30, value.Length)];

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

Still no Truncate method in 2016 for C# strings. But - Using C# 6.0 Syntax:

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

It works like a charm:

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

Just in case there's not enough answers here, here's mine :)

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

to use:

"I use it like this".Truncate(5,"~")

Seems no one has posted this yet:

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

Using the && operator makes it marginally better than the accepted answer.


There is nothing in .net for this that I am aware of - here is my version which adds "...":

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

I prefer jpierson's answer, but none of the examples here that I can see are handling an invalid maxLength parameter, such as when maxLength < 0.

Choices would be either handle the error in a try/catch, clamp the maxLength parameter min to 0, or if maxLength is less than 0 return an empty string.

Not optimized code:

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

My two cents with example length of 30 :

  var truncatedInput = string.IsNullOrEmpty(input) ? 
      string.Empty : 
      input.Substring(0, Math.Min(input.Length, 30));

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
    }

The popular library Humanizer has a Truncate method. To install with NuGet:

Install-Package Humanizer

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to truncate

Scala Doubles, and Precision Truncating Text in PHP? How can I truncate a double to only two decimal places in Java? SQL TRUNCATE DATABASE ? How to TRUNCATE ALL TABLES How to truncate a foreign key constrained table? Remove the last line from a file in Bash I want to truncate a text or line with ellipsis using JavaScript Limiting double to 3 decimal places I got error "The DELETE statement conflicted with the REFERENCE constraint" Truncate with condition