Menu

Методы строк в C#: Split, Replace, Contains, IndexOf, Trim, Join и другие

Методы String, которые используются каждый день в C#: Split с несколькими разделителями и опциями, Replace, Contains и поиск без учёта регистра, IndexOf и LastIndexOf, StartsWith и EndsWith, Trim, ToUpper и ToLower, PadLeft, Join, Concat и переворот строки.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

У System.String десятки методов. На этой странице описаны те, что выполняют большую часть работы в реальном коде, с важными опциями и ловушками. Для всех них действует одно правило: строки неизменяемы, поэтому каждый метод возвращает новую строку (или значение) и не меняет исходную. s.Trim(); в отдельной строке ничего не делает; пишите s = s.Trim();.

Split

Split разбивает строку на string[] по каждому разделителю:

Вывод:

3
apple
banana
cherry
red/green/ blue/yellow
INFO/started/ready

Обратите внимание на " blue": Split режет точно по разделителю и сохраняет пробелы. Две опции решают частые задачи очистки:

Вывод:

5
4
c#|dotnet|linq
key=[Subject] value=[Re: Meeting: Friday]
3

RemoveEmptyEntries убирает части нулевой длины, но не части, состоящие только из пробелов (" " выше уцелела). .NET 5 добавил StringSplitOptions.TrimEntries, и эти опции можно сочетать: tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) даёт чистый результат одним вызовом. Если передать null в качестве разделителя, строка разделится по любым пробельным символам; это обычный способ разбить текст на слова.

Для разделения по одному char (Split(',')) массив не нужен. Перегрузки, которые принимают char вместе с опциями или одну string, есть начиная с .NET Core 2.0; формы с массивом, использованные выше, работают везде, включая .NET Framework и Unity.

Replace

Replace заменяет каждое вхождение символа или подстроки:

Вывод:

5551234567
555.123.4567
Cats and dogs and CATS
dogs and dogs and dogs
dogs and cats and CATS
too many spaces

Перегрузка с аргументом StringComparison доступна в .NET Core 2.0 и новее. В .NET Framework замена без учёта регистра выполняется через Regex.Replace(text, Regex.Escape(find), replacement, RegexOptions.IgnoreCase). Замена на "" это способ удалить символы, а цепочка из нескольких вызовов Replace вполне годится для нескольких подстановок.

Contains, IndexOf, StartsWith и EndsWith

Эти методы выполняют поиск. Contains отвечает да или нет; IndexOf и LastIndexOf возвращают позицию или -1, если совпадения нет; StartsWith и EndsWith проверяют концы строки.

Вывод:

True
False
True
True
8
30
28
-1
16
False
True
True

Все они по умолчанию учитывают регистр. Contains(string, StringComparison) есть в .NET Core 2.1 и новее; форма IndexOf(...) >= 0 работает в любой версии, поэтому она встречается в старом коде. IndexOfAny(new[] { ',', ';' }) находит первый из нескольких символов.

Замечание о культуре: без StringComparison методы StartsWith, EndsWith, IndexOf(string) и CompareTo используют правила с учётом культуры, а Contains, Replace и IndexOf(char) сравнивают порядково. Явная передача StringComparison.Ordinal или OrdinalIgnoreCase убирает неоднозначность, и анализаторы кода это рекомендуют.

Trim, TrimStart и TrimEnd

Trim удаляет пробельные символы (пробелы, табуляции, переводы строк) с обоих концов. TrimStart и TrimEnd удаляют с одного конца. Если передать символы, удаляются они:

Вывод:

[ana@example.com]
[ana@example.com \n]
[  x]
SALE
7
path/to/dir
1,234.50

Trim затрагивает только концы; пробелы внутри строки сохраняются. TrimStart('0') для "000" возвращает пустую строку, поэтому строки с числами разбирайте через int.Parse, а не убирайте нули вручную.

ToUpper и ToLower

Вывод:

MAYA LOPEZ
maya lopez
MAYA LOPEZ
Coffee

ToUpper и ToLower следуют текущей культуре, поэтому в турецкой культуре "i".ToUpper() даёт заглавную İ с точкой, а не I. Для идентификаторов, ключей и имён файлов используйте ToUpperInvariant и ToLowerInvariant. Для сравнения используйте StringComparison вместо изменения регистра (см. строки). Чтобы сделать каждое слово с заглавной буквы, есть CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text), хотя он не трогает слова, которые уже целиком написаны заглавными.

PadLeft и PadRight

Дополнение добавляет символы, пока строка не достигнет заданной общей ширины. Это удобно для вывода фиксированной ширины и для дополнения кодов нулями:

Вывод:

000042
[Tea     ]
[     Tea]
Too long already
Espresso..  2.40
Latte.....  3.60
Mocha.....  3.95

Выравнивание в интерполяции ({name,-10}) делает то же самое прямо в строке.

Join и Concat

string.Join ставит разделитель между элементами любой коллекции. string.Concat соединяет без разделителя:

Вывод:

Ana, Ben, Chloe
1 + 2 + 3
True
2026-09
AnaBenChloe
Ana, Ben and Chloe

Join это правильный способ собрать список с разделителями: не остаётся лишнего разделителя в конце, который нужно удалять, и результат строится за один проход. Он вызывает ToString() у каждого элемента, поэтому работает и с числами, и с объектами.

Reverse, Insert и Remove

Метода string.Reverse, возвращающего строку, нет. Два обычных подхода:

Вывод:

desserts
desserts
True
2026/Q3-09
Hello
HelloWorld

word.Reverse() сам по себе возвращает IEnumerable<char>, а не строку; при выводе вы увидите имя типа. Оба способа переворачивают кодовые единицы UTF-16, что ломает символы из двух единиц (большинство эмодзи) и буквы с комбинируемыми диакритическими знаками.

Краткая справка

ЗадачаМетод
Разбить на частиs.Split(','), s.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries)
Заменить всеs.Replace("a", "b")
Содержитs.Contains("x"), s.Contains("x", StringComparison.OrdinalIgnoreCase)
Позицияs.IndexOf("x"), s.LastIndexOf('x') (-1, если нет)
Начинается или заканчивается наs.StartsWith("x"), s.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)
Убрать пробелы по краямs.Trim(), s.TrimStart(), s.TrimEnd()
Изменить регистрs.ToUpper(), s.ToLowerInvariant()
Дополнить до шириныs.PadLeft(6, '0'), s.PadRight(10)
Соединить коллекциюstring.Join(", ", items)
Часть строкиs.Substring(start, length)
Вставить или удалитьs.Insert(i, "x"), s.Remove(i, count)
Проверка на null или пустотуstring.IsNullOrWhiteSpace(s)

Часто задаваемые вопросы

Как разделить строку в C#?

text.Split(',') возвращает string[] из частей между запятыми. Несколько разделителей передаются массивом (Split(new[] { ',', ';' })), строковый разделитель через Split(new[] { ", " }, StringSplitOptions.None), а StringSplitOptions.RemoveEmptyEntries убирает пустые части, возникающие из-за сдвоенных разделителей. .NET 5 добавил StringSplitOptions.TrimEntries, чтобы обрезать пробелы у каждой части.

Как проверить, содержит ли строка другую строку без учёта регистра?

В .NET Core 2.1 и новее: text.Contains("error", StringComparison.OrdinalIgnoreCase). В .NET Framework, где такой перегрузки нет, используйте text.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0. Избегайте text.ToLower().Contains(...): это создаёт копию и в некоторых культурах может работать неправильно.

Изменяет ли String.Replace исходную строку в C#?

Нет. Строки неизменяемы, поэтому Replace возвращает новую строку с заменой всех вхождений и оставляет исходную как была. Пишите s = s.Replace("old", "new");. Метод заменяет все вхождения, а не только первое; чтобы заменить только первое, найдите его через IndexOf и соберите строку заново или вызовите Replace у экземпляра Regex с количеством 1.

Что возвращает IndexOf, если строка не найдена?

-1. Любой результат 0 или больше это позиция первого совпадения, считая с нуля. Всегда проверяйте на -1, прежде чем использовать результат как индекс, потому что Substring(-1) выбрасывает исключение, а Substring(-1 + 1) молча возвращает всю строку. LastIndexOf работает так же, но ищет с конца.

Как перевернуть строку в C#?

Скопируйте её в массив символов, переверните массив и создайте новую строку: char[] a = s.ToCharArray(); Array.Reverse(a); string r = new string(a);. С LINQ то же делает new string(s.Reverse().ToArray()). Оба способа переворачивают единицы UTF-16, поэтому эмодзи и комбинируемые диакритические знаки могут перемешаться.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ