ZetCode

C# split string

last modified November 6, 2026

In this article we show how to split strings in C# with the String.Split and Regex.Split methods, and how to split without allocations using spans.

The String.Split method divides a string into an array of substrings at the positions of one or more delimiters, which can be characters or strings. For more complex patterns, Regex.Split splits at the matches of a regular expression.

Split(char separator, StringSplitOptions options = None)
Split(char separator, int count, StringSplitOptions options = None)
Split(params char[]? separator)
Split(params ReadOnlySpan<char> separator)
Split(char[]? separator, int count)
Split(char[]? separator, StringSplitOptions options)
Split(char[]? separator, int count, StringSplitOptions options)
Split(string? separator, StringSplitOptions options = None)
Split(string? separator, int count, StringSplitOptions options = None)
Split(string[]? separator, StringSplitOptions options)
Split(string[]? separator, int count, StringSplitOptions options)

In .NET 10, String.Split has eleven overloads. They differ in the type of the delimiter, the maximum number of substrings, and the StringSplitOptions flags.

Splitting by a single character

The basic use of Split divides a sentence into words at the spaces.

Program.cs
string text = "There is an old hawk in the sky";
string[] words = text.Split(' ');

Console.WriteLine($"{words.Length} words");

foreach (string word in words)
{
    Console.WriteLine(word);
}

The program splits a sentence into words and prints them.

string[] words = text.Split(' ');

The method returns a new array of strings. The delimiters are not part of the substrings.

$ dotnet run
8 words
There
is
an
old
hawk
in
the
sky

StringSplitOptions

Consecutive delimiters, or a delimiter at the beginning or end of the string, produce empty strings. The StringSplitOptions flags control this.

Program.cs
string text = " falcon, owl,, eagle ,  hawk ,";

string[] a = text.Split(',');
Console.WriteLine(string.Join("|", a));

string[] b = text.Split(',', StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(string.Join("|", b));

string[] c = text.Split(',', StringSplitOptions.TrimEntries);
Console.WriteLine(string.Join("|", c));

string[] d = text.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
Console.WriteLine(string.Join("|", d));

We split a messy comma-separated list with each combination of options. The substrings are joined with a vertical bar to make the spaces and empty entries visible.

string[] b = text.Split(',', StringSplitOptions.RemoveEmptyEntries);

The empty strings between the two commas and after the last comma are removed, but the substrings keep their spaces.

string[] c = text.Split(',', StringSplitOptions.TrimEntries);

The spaces are trimmed, but empty entries remain.

string[] d = text.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

The options are flags and can be combined. With both, entries that become empty after trimming are removed too. This is the usual choice for parsing user input.

$ dotnet run
 falcon| owl|| eagle |  hawk |
 falcon| owl| eagle |  hawk 
falcon|owl||eagle|hawk|
falcon|owl|eagle|hawk

Splitting by multiple characters

Split accepts several delimiter characters. Called without arguments, it splits at whitespace characters.

Program.cs
string text = "falcon;eagle,forest sky;cloud,water rock";

string[] words = text.Split([',', ';', ' ']);
Console.WriteLine(string.Join("|", words));

string messy = "There are\t\tmany  clouds\nin the sky";

string[] parts = messy.Split();
Console.WriteLine(string.Join("|", parts));

string[] clean = messy.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(string.Join("|", clean));

We split a string at commas, semicolons, and spaces, and then a string with mixed whitespace.

string[] words = text.Split([',', ';', ' ']);

The collection expression creates the separators. The string is split wherever any of the characters occurs.

string[] parts = messy.Split();

Without separators, Split uses all whitespace characters, including tabs and newlines. Consecutive whitespace still produces empty entries.

string[] clean = messy.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);

To split at any whitespace and remove empty entries, we pass null as the separator array. The cast selects the right overload.

$ dotnet run
falcon|eagle|forest|sky|cloud|water|rock
There|are||many||clouds|in|the|sky
There|are|many|clouds|in|the|sky

Limiting the number of substrings

The count parameter sets the maximum number of substrings. The last substring contains the rest of the string, including the remaining delimiters.

Program.cs
string text = "falcon,eagle,forest,sky,cloud,water,rock,wind";

string[] words = text.Split(',', 4);
Array.ForEach(words, Console.WriteLine);

string header = "Content-Type: text/html; charset=utf-8";
string[] kv = header.Split(':', 2, StringSplitOptions.TrimEntries);
Console.WriteLine($"name: {kv[0]}, value: {kv[1]}");

We split a list into at most four parts and an HTTP header into a name and a value.

string[] kv = header.Split(':', 2, StringSplitOptions.TrimEntries);

The limit of two parts splits only at the first colon. This is useful for name-value pairs whose values may contain the delimiter.

$ dotnet run
falcon
eagle
forest
sky,cloud,water,rock,wind
name: Content-Type, value: text/html; charset=utf-8

Splitting by strings

The delimiter can be a string or an array of strings.

Program.cs
string birds = "hawkxxowlxxvulturexxeagle";
Console.WriteLine(string.Join(", ", birds.Split("xx")));

string text = "line one\r\nline two\nline three\r\n";

string[] lines = text.Split(["\r\n", "\n"], StringSplitOptions.RemoveEmptyEntries);

foreach (string line in lines)
{
    Console.WriteLine($"[{line}]");
}

string data = "red AND green OR blue AND yellow";
string[] colors = data.Split([" AND ", " OR "], StringSplitOptions.None);
Console.WriteLine(string.Join(", ", colors));

We split at a two-character delimiter, at Windows and Unix line endings, and at two keywords.

string[] lines = text.Split(["\r\n", "\n"], StringSplitOptions.RemoveEmptyEntries);

At each position, the separators are tried in the order of the array. The order matters only when one separator is a prefix of another; for instance, "abcd".Split(["b", "bc"], ...) gives "a" and "cd", while ["bc", "b"] gives "a" and "d". Here the two line endings start with different characters, so the order does not matter.

$ dotnet run
hawk, owl, vulture, eagle
[line one]
[line two]
[line three]
red, green, blue, yellow

Parsing structured data

Splitting is often the first step of parsing simple text formats.

Program.cs
string csv = """
    John Doe,gardener,1230
    Roger Roe,driver,1460
    Lucy Novak,teacher,2100
    """;

var users = new List<User>();

foreach (string line in csv.Split('\n', StringSplitOptions.RemoveEmptyEntries))
{
    string[] f = line.Split(',', StringSplitOptions.TrimEntries);
    users.Add(new User(f[0], f[1], int.Parse(f[2])));
}

users.ForEach(Console.WriteLine);

string conn = "Server=localhost;Port=5432;Database=testdb;User Id=admin";

Dictionary<string, string> settings = conn
    .Split(';', StringSplitOptions.RemoveEmptyEntries)
    .Select(pair => pair.Split('=', 2))
    .ToDictionary(kv => kv[0], kv => kv[1]);

Console.WriteLine($"{settings["Database"]} on {settings["Server"]}:{settings["Port"]}");

record User(string Name, string Occupation, int Salary);

We parse CSV lines into records and a connection string into a dictionary.

foreach (string line in csv.Split('\n', StringSplitOptions.RemoveEmptyEntries))
{
    string[] f = line.Split(',', StringSplitOptions.TrimEntries);
    users.Add(new User(f[0], f[1], int.Parse(f[2])));
}

First we split the text into lines, then each line into fields. Real CSV files may contain quoted fields with commas; use a CSV library such as CsvHelper for those.

Dictionary<string, string> settings = conn
    .Split(';', StringSplitOptions.RemoveEmptyEntries)
    .Select(pair => pair.Split('=', 2))
    .ToDictionary(kv => kv[0], kv => kv[1]);

The connection string is split into pairs, each pair into a key and a value, and LINQ builds a dictionary.

$ dotnet run
User { Name = John Doe, Occupation = gardener, Salary = 1230 }
User { Name = Roger Roe, Occupation = driver, Salary = 1460 }
User { Name = Lucy Novak, Occupation = teacher, Salary = 2100 }
testdb on localhost:5432

Splitting with Regex.Split

The Regex.Split method splits a string at the matches of a regular expression. It has three static and three instance overloads.

Program.cs
using System.Text.RegularExpressions;

string text = "There are\t\t many clouds   in the \n sky.";

string[] words = Regex.Split(text, @"\s+");
Console.WriteLine(string.Join("|", words));

string expr = "12+5-3*2";

Console.WriteLine(string.Join(" ", Regex.Split(expr, @"[+\-*]")));
Console.WriteLine(string.Join(" ", Regex.Split(expr, @"([+\-*])")));

string name = "parseHtmlDocumentToXml";
string[] parts = Regex.Split(name, @"(?<=[a-z])(?=[A-Z])");
Console.WriteLine(string.Join(" ", parts));

string dates = "2026-11-06, 2025/04/20; 2024.01.19";
foreach (string d in Regex.Split(dates, @"[,;]\s*"))
{
    Console.WriteLine(string.Join(" ", Regex.Split(d, @"[-/.]")));
}

We split at runs of whitespace, at arithmetic operators, at the word boundaries of a camelCase identifier, and at various date separators.

string[] words = Regex.Split(text, @"\s+");

The \s+ pattern matches one or more whitespace characters, so consecutive spaces and tabs produce no empty entries.

Console.WriteLine(string.Join(" ", Regex.Split(expr, @"([+\-*])")));

If the pattern contains a capturing group, the captured text is included in the result. This keeps the operators between the numbers.

string[] parts = Regex.Split(name, @"(?<=[a-z])(?=[A-Z])");

Lookbehind and lookahead assertions match an empty position between a lowercase and an uppercase letter. No characters are removed. For more on patterns, see the C# regular expressions tutorial.

$ dotnet run
There|are|many|clouds|in|the|sky.
12 5 3 2
12 + 5 - 3 * 2
parse Html Document To Xml
2026 11 06
2025 04 20
2024 01 19

Splitting spans without allocations

Since .NET 9, the MemoryExtensions.Split method splits a ReadOnlySpan<char> lazily. Instead of an array of new strings, it returns the Range of each part, so no memory is allocated.

Program.cs
string line = "falcon,eagle,forest,sky,cloud";

ReadOnlySpan<char> span = line;

foreach (Range r in span.Split(','))
{
    ReadOnlySpan<char> word = span[r];
    Console.WriteLine($"{word} ({word.Length})");
}

string nums = "4 8 15 16 23 42";
int sum = 0;

foreach (Range r in nums.AsSpan().Split(' '))
{
    sum += int.Parse(nums.AsSpan(r));
}

Console.WriteLine($"sum: {sum}");

We print the words of a line and sum numbers from a string.

foreach (Range r in span.Split(','))
{
    ReadOnlySpan<char> word = span[r];

The enumerator yields ranges; slicing the span with a range gives the part.

sum += int.Parse(nums.AsSpan(r));

Many parsing methods accept spans, so we parse the numbers without creating any substrings. This matters in hot paths that process large amounts of text.

$ dotnet run
falcon (6)
eagle (5)
forest (6)
sky (3)
cloud (5)
sum: 108

Joining strings

The string.Join method is the inverse of Split. It concatenates elements with a separator.

Program.cs
List<string> words = ["falcon", "wood", "sky", "water"];

Console.WriteLine(string.Join(",", words));
Console.WriteLine(string.Join(" - ", words));
Console.WriteLine(string.Join('|', 1, 2, 3, 4));

string text = "falcon wood  sky   water";
string normalized = string.Join(' ', text.Split(' ', StringSplitOptions.RemoveEmptyEntries));
Console.WriteLine(normalized);

We join words with different separators and normalize whitespace with a combination of Split and Join.

string normalized = string.Join(' ', text.Split(' ', StringSplitOptions.RemoveEmptyEntries));

Splitting with RemoveEmptyEntries and joining with a single space collapses runs of spaces.

$ dotnet run
falcon,wood,sky,water
falcon - wood - sky - water
1|2|3|4
falcon wood sky water

Source

Divide strings using String.Split

In this article we have split strings in C# with String.Split, Regex.Split, and span splitting.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.