C# Substring

Array Collections File Keyword String .NET Cast Class Data Dictionary Enum Exception If Interface Lambda LINQ List Loop Method Number Process Property Regex Sort Split StringBuilder Struct Substring Switch Time Windows

Substring

Substring. This method extracts strings. It requires the location of the substring (a start index, a length). It then returns a new string with the characters in that range.


About part

Strings are immutable. We will never change their opinions about things. Substring does not change their data. It copies fragments from them into new buffers.


Two

First part. Here we extract the first part of a string into a new string. We can use the Substring method with two parameters—the first is 0 and the second is the desired length.

Argument 1:The starting index of the substring. Please remember strings are indexed with the first character 0.

Argument 2:The length of the substring part. This is not the final index, but the count of characters in the substring we want.

Length
Based on:

.NET 4.5

C# program that uses Substring

using System;

class Program
{
    static void Main()
    {
	string input = "OneTwoThree";

	// Get first three characters.
	string sub = input.Substring(0, 3);
	Console.WriteLine("Substring: {0}", sub);
    }
}

Output

Substring: One
Method call

Methods. These are two Substring overloads. The first integer argument is always the start index. The second, optional argument is the desired length—not the end index.

Substring parameters

Substring(0, 3)    Returns substring of first 3 chars.
Substring(3, 3)    Returns substring of second 3 chars.
Substring(6)       Returns substring of all chars after first 6.
Program

One parameter. This Substring overload receives just the start index int. The second parameter is considered the largest possible, meaning the substring ends at the last char.

Program:The program describes logic that takes all the characters in the input string excluding the first three.

Result:The end result is that you extract the last several characters. The length is reduced by three.

C# program that calls Substring, one argument

using System;

class Program
{
    static void Main()
    {
	string input = "OneTwoThree";
	// Indexes:
	// 0:'O'
	// 1:'n'
	// 2:'e'
	// 3:'T'
	// 4:'w' ...

	string sub = input.Substring(3);
	Console.WriteLine("Substring: {0}", sub);
    }
}

Output

Substring: TwoThree
Char type example: letter C

Middle chars. Here we take several characters in the middle of a string and place them into a new string. To take a middle substring, pass two arguments to Substring.

Note:We will want each argument to be a non-zero value to avoid the edge characters. Be careful to validate arguments.

Parameters:In this example, the two parameters say, "I want the substring at index 3 with a length of three."

C# program that uses Substring, two arguments

using System;

class Program
{
    static void Main()
    {
	string input = "OneTwoThree";

	string sub = input.Substring(3, 3);
	Console.WriteLine("Substring: {0}", sub);
    }
}

Output

Substring: Two

Avoid chars. Here we eliminate the last few chars in a string. This example eliminates the last five characters from the input string. It returns a new string without them.

Info:This method reduces the length of a string. It will cause an error if the string is too short—a check would be needed.

Remove:The Remove method can be used to remove parts of strings too. It just internally forwards to Substring with the correct arguments.

Remove
C# program that uses Substring, ending characters

using System;

class Program
{
    static void Main()
    {
	string input = "OneTwoThree";

	string sub = input.Substring(0, input.Length - 5);
	Console.WriteLine("Substring: {0}", sub);
    }
}

Output

Substring: OneTwo
Slice

Notation. Other languages use different arguments for substring. For example, in Java the start index and the end index are specified—the length of the substring is not needed.

Substring, Java

Slice:In Python and JavaScript, slice notation is often used. We can use relative indexes.

Slice, Python
Programming tip

An extension. We can add an extension method to "slice" strings. So you can specify indexes, as in Java or Python, to get substrings in your C# program.

String Slice
ABC: letters

Research. Here is some reference material on MSDN. I recommend using all resources possible to improve your knowledge. But MSDN is often confusing.

Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.

String.Substring Method: MSDN
Error

Exceptions are raised when Substring() is called with incorrect arguments. Exceptions can be scary, but they are trying to help you. This example triggers the ArgumentOutOfRangeException.

Tip:When you try to go beyond the string length, or use an argument < 0, you get an ArgumentOutOfRangeException.

ArgumentException
C# program that shows exceptions

using System;

class Program
{
    static void Main()
    {
	string input = "OneTwoThree";

	try
	{
	    string sub = input.Substring(-1);
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}

	try
	{
	    string sub = input.Substring(0, 100);
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}
    }
}

Output

System.ArgumentOutOfRangeException
System.String.InternalSubStringWithChecks

System.ArgumentOutOfRangeException
System.String.InternalSubStringWithChecks
Performance fast-forward

Performance is important. String-related allocations can be a burden. I wanted to see if taking characters and putting them into a char array is faster than calling Substring.

Result:Substring is faster. But if you want to extract only certain characters, consider the char[] approach shown.

Char Array

Tip:It is best to use Substring when it has equivalent behavior. Code is shorter, simpler and easier to read.

Data tested

string s = "onetwothree"; // Input

Char array method version

char[] c = new char[3];
c[0] = s[3];
c[1] = s[4];
c[2] = s[5];
string x = new string(c); // "two"
if (x == null)
{
}

Substring version

string x = s.Substring(3, 3); // "two"
if (x == null)
{
}

Substring benchmark result

New char[] array: 2382 ms
Substring:        2053 ms [faster]
Char type

One character. It is possible to take a one-character substring. But if we simply use the string indexer to get a character, we will have better performance.

Note:Substring creates an object on the heap. The string indexer just returns a char, which is an integer-like value—this is faster.

Char
C# program that uses char, Substring

using System;

class Program
{
    static void Main()
    {
	string value = "cat";
	// ... In many programs, we can use a char instead of Substring.
	Console.WriteLine(value[0]);
	Console.WriteLine(value.Substring(0, 1));
    }
}

Output

c
c
Logic

With logic, we can avoid invoking Substring. Suppose a program gets the same Substring over and over again. We can handle this case in code, and return a literal.

Here:I introduce simple code in SubstringFirst3 that optimizes the case of getting the first 3 letters of the string "Windows."

So:In a program that happens to do this operation many times, this logic would reduce allocations and increase speed.

C# that avoids Substring

using System;

class Program
{
    static string SubstringFirst3(string value)
    {
	// ... Use logic to avoid creating a new string.
	if (value == "Windows")
	{
	    return "Win";
	}
	else
	{
	    return value.Substring(0, 3);
	}
    }

    static void Main()
    {
	Console.WriteLine(SubstringFirst3("Windows"));
	Console.WriteLine(SubstringFirst3("Computer"));
    }
}

Output

Win
Com
Split

Rewrite Split. Internally the Split method finds Substrings and places them into a string array. With Substring and IndexOf we can duplicate this logic.

SplitIndexOf

Sometimes:We only need a single part of a large string. If we avoid Split in this case, we can avoid creating many strings.

Bugs:This style of optimization can yield code that is fast but prone to bugs. Be prepared to fix problems.


C# language

A brief history of Substring. This method allocates a new string. We invoke it with one or two arguments—the start and length. It does not receive an end index.


Finally, we learned about Slice, Substring exceptions, and Substring performance. As with all string methods, avoiding them when possible is often the best optimization.

C#