[c#] How do I get the last four characters from a string in C#?

Suppose I have a string:

"34234234d124"

I want to get the last four characters of this string which is "d124". I can use SubString, but it needs a couple of lines of code, including naming a variable.

Is it possible to get this result in one expression with C#?

This question is related to c# string

The answer is


Update 2020: C# 8.0 finally makes this easy:

> "C# 8.0 finally makes this easy"[^4..]
"easy"

You can also slice arrays in the same way, see Indices and ranges.


Using Substring is actually quite short and readable:

 var result = mystring.Substring(mystring.Length - Math.Min(4, mystring.Length));
 // result == "d124"

Suggest using TakeLast method, for example: new String(text.TakeLast(4).ToArray())


string var = "12345678";

var = var[^4..];

// var = "5678"

It is just this:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);

You can simply use Substring method of C#. For ex.

string str = "1110000";
string lastFourDigits = str.Substring((str.Length - 4), 4);

It will return result 0000.


A simple solution would be:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);

Compared to some previous answers, the main difference is that this piece of code takes into consideration when the input string is:

  1. Null
  2. Longer than or matching the requested length
  3. Shorter than the requested length.

Here it is:

public static class StringExtensions
{
    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - length, length);
    }

    public static string MyLast(this string str, int length)
    {
        if (str == null)
            return null;
        else if (str.Length >= length)
            return str.Substring(str.Length - length, length);
        else
            return str;
    }
}

string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)

mystring.Substring(Math.Max(0, mystring.Length - 4)); //how many lines is this?

If you're positive the length of your string is at least 4, then it's even shorter:

mystring.Substring(mystring.Length - 4);

All you have to do is..

String result = mystring.Substring(mystring.Length - 4);

Use a generic Last<T>. That will work with ANY IEnumerable, including string.

public static IEnumerable<T> Last<T>(this IEnumerable<T> enumerable, int nLastElements)
{
    int count = Math.Min(enumerable.Count(), nLastElements);
    for (int i = enumerable.Count() - count; i < enumerable.Count(); i++)
    {
        yield return enumerable.ElementAt(i);
    }
}

And a specific one for string:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}

I would like to extend the existing answer mentioning using new ranges in C# 8 or higher: To make the code usable for all possible strings. If you want to copy code, I suggest example 5 or 6.

string mystring ="C# 8.0 finally makes slicing possible";

1: Slicing taking the end part- by specifying how many characters to omit from the beginning- this is, what VS 2019 suggests:

string example1 = mystring[Math.Max(0, mystring.Length - 4)..] ;

2: Slicing taking the end part- by specifying how many characters to take from the end:

string example2 = mystring[^Math.Min(mystring.Length, 4)..] ;

3: Slicing taking the end part- by replacing Max/Min with the ?: operator:

string example3 = (mystring.length > 4)? mystring[^4..] : mystring); 

Personally, I like the second and third variant more than the first.

MS doc reference for Indices and ranges:

Null? But we are not done yet concerning universality. Every example so far will throw an exception for null strings. To consider null (if you don´t use non-nullable strings with C# 8 or higher), and to do it without 'if' (classic example 'with if' already given in another answer) we need:

4: Slicing considering null- by specifying how many characters to omit:

string example4 = mystring?[Math.Max(0, mystring.Length - 4)..] ?? string.Empty;

5: Slicing considering null- by specifying how many characters to take:

string example5 = mystring?[^Math.Min(mystring.Length, 4)..] ?? string.Empty;

6: Slicing considering null with the ?: operator (and two other '?' operators ;-) :
(You cannot put that in a whole in a string interpolation e.g. for WriteLine.)

string example6 = (mystring?.Length > 4) ? filePath[^4..] : mystring ?? string.Empty;

7: Equivalent variant with good old Substring() for C# 6 or 7.x:
(You cannot put that in a whole in a string interpolation e.g. for WriteLine.)

string example7 = (mystring?.Length > 4) ? mystring.Substring(mystring.Length- 4) : mystring ?? string.Empty;

Graceful degradation? I like the new features of C#. Putting them on one line like in the last examples maybe looks a bit excessive. We ended up a little perl´ish didn´t we? But it´s a good example for learning and ok for me to use it once in a tested library method. Even better that we can get rid of null in modern C# if we want and avoid all this null-specific handling.

Such a library/extension method as a shortcut is really useful. Despite the advances in C# you have to write your own to get something easier to use than repeating the code above for every small string manipulation need.

I am one of those who began with BASIC, and 40 years ago there was already Right$(,). Funny, that it is possible to use Strings.Right(,) from VB with C# still too as was shown in another answer.

C# has chosen precision over graceful degradation (in opposite to old BASIC). So copy any appropriate variant you like in these answers and define a graceful shortcut function for yourself, mine is an extension function called RightChars(int).


Here is another alternative that shouldn't perform too badly (because of deferred execution):

new string(mystring.Reverse().Take(4).Reverse().ToArray());

Although an extension method for the purpose mystring.Last(4) is clearly the cleanest solution, albeit a bit more work.


assuming you wanted the strings in between a string which is located 10 characters from the last character and you need only 3 characters.

Let's say StreamSelected = "rtsp://72.142.0.230:80/SMIL-CHAN-273/4CIF-273.stream"

In the above, I need to extract the "273" that I will use in database query

        //find the length of the string            
        int streamLen=StreamSelected.Length;

        //now remove all characters except the last 10 characters
        string streamLessTen = StreamSelected.Remove(0,(streamLen - 10));   

        //extract the 3 characters using substring starting from index 0
        //show Result is a TextBox (txtStreamSubs) with 
        txtStreamSubs.Text = streamLessTen.Substring(0, 3);

You can use an extension method:

public static class StringExtension
{
    public static string GetLast(this string source, int tail_length)
    {
       if(tail_length >= source.Length)
          return source;
       return source.Substring(source.Length - tail_length);
    }
}

And then call:

string mystring = "34234234d124";
string res = mystring.GetLast(4);

I threw together some code modified from various sources that will get the results you want, and do a lot more besides. I've allowed for negative int values, int values that exceed the length of the string, and for end index being less than the start index. In that last case, the method returns a reverse-order substring. There are plenty of comments, but let me know if anything is unclear or just crazy. I was playing around with this to see what all I might use it for.

    /// <summary>
    /// Returns characters slices from string between two indexes.
    /// 
    /// If start or end are negative, their indexes will be calculated counting 
    /// back from the end of the source string. 
    /// If the end param is less than the start param, the Slice will return a 
    /// substring in reverse order.
    /// 
    /// <param name="source">String the extension method will operate upon.</param>
    /// <param name="startIndex">Starting index, may be negative.</param>
    /// <param name="endIndex">Ending index, may be negative).</param>
    /// </summary>
    public static string Slice(this string source, int startIndex, int endIndex = int.MaxValue)
    {
        // If startIndex or endIndex exceeds the length of the string they will be set 
        // to zero if negative, or source.Length if positive.
        if (source.ExceedsLength(startIndex)) startIndex = startIndex < 0 ? 0 : source.Length;
        if (source.ExceedsLength(endIndex)) endIndex = endIndex < 0 ? 0 : source.Length;

        // Negative values count back from the end of the source string.
        if (startIndex < 0) startIndex = source.Length + startIndex;
        if (endIndex < 0) endIndex = source.Length + endIndex;         

        // Calculate length of characters to slice from string.
        int length = Math.Abs(endIndex - startIndex);
        // If the endIndex is less than the startIndex, return a reversed substring.
        if (endIndex < startIndex) return source.Substring(endIndex, length).Reverse();

        return source.Substring(startIndex, length);
    }

    /// <summary>
    /// Reverses character order in a string.
    /// </summary>
    /// <param name="source"></param>
    /// <returns>string</returns>
    public static string Reverse(this string source)
    {
        char[] charArray = source.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    /// <summary>
    /// Verifies that the index is within the range of the string source.
    /// </summary>
    /// <param name="source"></param>
    /// <param name="index"></param>
    /// <returns>bool</returns>
    public static bool ExceedsLength(this string source, int index)
    {
        return Math.Abs(index) > source.Length ? true : false;
    }

So if you have a string like "This is an extension method", here are some examples and results to expect.

var s = "This is an extension method";
// If you want to slice off end characters, just supply a negative startIndex value
// but no endIndex value (or an endIndex value >= to the source string length).
Console.WriteLine(s.Slice(-5));
// Returns "ethod".
Console.WriteLine(s.Slice(-5, 10));
// Results in a startIndex of 22 (counting 5 back from the end).
// Since that is greater than the endIndex of 10, the result is reversed.
// Returns "m noisnetxe"
Console.WriteLine(s.Slice(2, 15));
// Returns "is is an exte"

Hopefully this version is helpful to someone. It operates just like normal if you don't use any negative numbers, and provides defaults for out of range params.


Definition:

public static string GetLast(string source, int last)
{
     return last >= source.Length ? source : source.Substring(source.Length - last);
}

Usage:

GetLast("string of", 2);

Result:

of


Ok, so I see this is an old post, but why are we rewriting code that is already provided in the framework?

I would suggest that you add a reference to the framework DLL "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);

string var = "12345678";

if (var.Length >= 4)
{
    var = var.substring(var.Length - 4, 4)
}

// result = "5678"

mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;

This won't fail for any length string.

string mystring = "34234234d124";
string last4 = Regex.Match(mystring, "(?!.{5}).*").Value;
// last4 = "d124"
last4 = Regex.Match("d12", "(?!.{5}).*").Value;
// last4 = "d12"

This is probably overkill for the task at hand, but if there needs to be additional validation, it can possibly be added to the regular expression.

Edit: I think this regex would be more efficient:

@".{4}\Z"