String Methods

The string type comes with methods for nearly every text task: changing case, trimming, searching, extracting, replacing, splitting and padding. Remember that every one of them returns a new string — the original never changes.

Case and trimming

C#
string input = "   Hello, World!   ";

Console.WriteLine($"[{input.Trim()}]");
Console.WriteLine($"[{input.TrimStart()}]");
Console.WriteLine($"[{input.TrimEnd()}]");
Console.WriteLine(input.Trim().ToUpper());
Console.WriteLine(input.Trim().ToLower());
Console.WriteLine("--==Title==--".Trim('-', '='));
Output
[Hello, World!]
[Hello, World!   ]
[   Hello, World!]
HELLO, WORLD!
hello, world!
Title

Without arguments, the trim methods remove all whitespace (spaces, tabs, line breaks); with arguments they remove the characters you list.

Searching

C#
string text = "The rain in Spain stays mainly in the plain";

Console.WriteLine(text.Contains("Spain"));
Console.WriteLine(text.Contains("spain"));
Console.WriteLine(text.Contains("spain", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(text.StartsWith("The"));
Console.WriteLine(text.EndsWith("plain"));
Console.WriteLine(text.IndexOf("ain"));
Console.WriteLine(text.LastIndexOf("ain"));
Console.WriteLine(text.IndexOf("ain", 6));    // start searching at position 6
Console.WriteLine(text.IndexOf("snow"));
Output
True
False
True
True
True
5
40
14
-1

IndexOf returns the position of the first match, or -1 if there's none. A loop can use the start position to find every match:

C#
string text = "The rain in Spain stays mainly in the plain";
int count = 0;
int pos = text.IndexOf("ain");

while (pos != -1)
{
    count++;
    pos = text.IndexOf("ain", pos + 1);
}
Console.WriteLine($"'ain' appears {count} times");
Output
'ain' appears 4 times

Extracting parts

Substring(start, length) copies part of a string. Ranges ([start..end], end not included) do the same with less arithmetic:

C#
string email = "maria.lopez@example.com";
int at = email.IndexOf('@');

string user = email.Substring(0, at);
string domain = email.Substring(at + 1);
Console.WriteLine(user);
Console.WriteLine(domain);

Console.WriteLine(email[..at]);         // same as Substring(0, at)
Console.WriteLine(email[(at + 1)..]);   // from at + 1 to the end
Console.WriteLine(email[^3..]);         // last three characters
Output
maria.lopez
example.com
maria.lopez
example.com
com

Asking for characters beyond the end throws an ArgumentOutOfRangeException, so check lengths before slicing text you don't control.

Replacing, inserting and removing

C#
string s = "I like cats. Cats are great.";

Console.WriteLine(s.Replace("cats", "dogs"));
Console.WriteLine(s.Replace("cats", "dogs", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(s.Replace('.', '!'));
Console.WriteLine("2026-10-08".Replace("-", ""));
Console.WriteLine("Hello World".Insert(5, ","));
Console.WriteLine("Hello, cruel World".Remove(5, 7));
Output
I like dogs. Cats are great.
I like dogs. dogs are great.
I like cats! Cats are great!
20261008
Hello, World
Hello World

Splitting and joining

Split breaks a string into an array at a separator; string.Join does the reverse:

C#
string csv = "Oslo,Bergen,,Trondheim, Stavanger";

string[] raw = csv.Split(',');
Console.WriteLine(raw.Length);

string[] clean = csv.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
Console.WriteLine(clean.Length);
Console.WriteLine(string.Join(" | ", clean));

string sentence = "split  on   any whitespace";
string[] words = sentence.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(string.Join("_", words));

string[] keyValue = "timeout=30=seconds".Split('=', 2);   // at most 2 parts
Console.WriteLine($"{keyValue[0]} -> {keyValue[1]}");
Output
5
4
Oslo | Bergen | Trondheim | Stavanger
split_on_any_whitespace
timeout -> 30=seconds

Padding

PadLeft and PadRight extend a string to a given width — useful for simple tables and fixed-width formats:

C#
string[] items = ["Tea", "Coffee", "Hot chocolate"];
decimal[] prices = [2.5m, 3.2m, 3.95m];

for (int i = 0; i < items.Length; i++)
{
    Console.WriteLine(items[i].PadRight(15, '.') + prices[i].ToString("0.00").PadLeft(6));
}
Console.WriteLine("42".PadLeft(6, '0'));
Output
Tea............  2.50
Coffee.........  3.20
Hot chocolate..  3.95
000042

Characters and arrays

To work on individual characters, convert to a char array and back. The char type has handy tests such as char.IsLetter, char.IsDigit, char.IsUpper and char.IsWhiteSpace:

C#
string word = "stressed";
char[] letters = word.ToCharArray();
Array.Reverse(letters);
Console.WriteLine(new string(letters));

string password = "Secr3t!";
int digits = 0, upper = 0, symbols = 0;
foreach (char c in password)
{
    if (char.IsDigit(c)) digits++;
    else if (char.IsUpper(c)) upper++;
    else if (!char.IsLetter(c)) symbols++;
}
Console.WriteLine($"digits {digits}, upper {upper}, symbols {symbols}");
Output
desserts
digits 1, upper 1, symbols 1

Quick reference

MethodReturns
ToUpper(), ToLower()Copy with changed case
Trim(), TrimStart(), TrimEnd()Copy without surrounding whitespace (or given characters)
Contains, StartsWith, EndsWithbool
IndexOf, LastIndexOfPosition, or -1
Substring(start, length), s[a..b]Part of the string
Replace(old, new)Copy with replacements
Insert, RemoveCopy with text added or removed
Split(separator)string[]
string.Join(separator, items)One string
PadLeft(width), PadRight(width)Copy padded to a width

Try it yourself

Turn a title into a URL "slug": lower-case, trimmed, with spaces replaced by hyphens and punctuation removed.

Try it yourself · Program.cs
Edit the code, copy it into Program.cs and run it with dotnet run Program.cs (.NET 10 or later). How to set up .NET
Output
hello-world-c-strings-explained