Avatar ·

Как разбить строку по другой строке (не символу) в C#?

Всем привет! Я новичок в C# и столкнулся с проблемой при работе со строками. Мне нужно разбить строку на массив подстрок, используя в качестве разделителя не один символ, а целую строку. Например, у меня есть строка: ```csharp string data = "Привет||мир||C#"; ``` Я хочу получить массив: `["Привет", "мир", "C#"]`, используя разделитель `"||"`. Проблема в том, что стандартный метод `string.Split()` принимает только одиночные символы или массив символов. Я пробовал написать так: ```csharp string[] parts = data.Split("||"); ``` Но компилятор выдаёт ошибку, что нельзя преобразовать строку в char. Я также пробовал использовать перегрузку с `StringSplitOptions`, но всё равно не получается. Я знаю, что можно сделать это вручную через цикл, но это некрасиво и, наверное, есть стандартное решение. Подскажите, как правильно разбить строку по подстроке в C#? Может быть, есть какой-то специальный метод или нужно использовать регулярные выражения? Буду благодарен за примеры кода. P.S. Использую .NET Framework 4.7.2, но если решение есть только в новых версиях, тоже напишите. <<>>

Используйте метод string.Split() с перегрузкой, принимающей строку (требуется .NET Core 2.0+ / .NET 5+)

Начиная с .NET Core 2.0 (и во всех версиях .NET 5/6/7/8/9), у метода string.Split() появилась перегрузка, которая принимает строку (или массив строк) в качестве разделителя. Это самое простое и элегантное решение:

string data = "Привет||мир||C#";
string[] parts = data.Split("||");

Если вы используете .NET Framework 4.7.2, эта перегрузка недоступна. В этом случае вам нужно использовать один из альтернативных подходов, описанных ниже.

Альтернатива 1: Использование string.Split() с массивом строк и StringSplitOptions

Даже в старых версиях .NET Framework есть перегрузка Split(string[], StringSplitOptions), которая принимает массив строк-разделителей:

string data = "Привет||мир||C#";
string[] parts = data.Split(new string[] { "||" }, StringSplitOptions.None);

Преимущества этого метода:

  • Работает во всех версиях .NET (включая .NET Framework 2.0+)
  • Можно указать несколько разных разделителей: new string[] { "||", "|", "&&" }
  • Есть опция StringSplitOptions.RemoveEmptyEntries для удаления пустых элементов

Пример с удалением пустых строк:

string data = "Привет||мир||C#";
string[] parts = data.Split(
    new string[] { "||" },
    StringSplitOptions.RemoveEmptyEntries);

Альтернатива 2: Использование Regex.Split()

Если вам нужна более гибкая логика разделения (например, с учётом регистра или сложных шаблонов), используйте регулярные выражения:

using System.Text.RegularExpressions;

string data = "Привет||мир||C#";
string[] parts = Regex.Split(data, @"\|\|");

Обратите внимание: символ | в регулярных выражениях является специальным (означает "ИЛИ"), поэтому его нужно экранировать \|. Если разделитель не содержит спецсимволов, экранирование не требуется.

Для разделения без учёта регистра:

string[] parts = Regex.Split(data, Regex.Escape("||"), RegexOptions.IgnoreCase);

Метод Regex.Escape() автоматически экранирует все спецсимволы, что очень удобно, если разделитель вводится пользователем.

Альтернатива 3: Ручная реализация через IndexOf() и Substring()

Если по каким-то причинам вы не хотите использовать стандартные методы, можно реализовать разбиение вручную:

public static string[] SplitByString(string input, string separator, StringSplitOptions options = StringSplitOptions.None)
{
    if (string.IsNullOrEmpty(input)) return Array.Empty<string>();

    var result = new List<string>();
    int startIndex = 0;
    int sepLength = separator.Length;

    while (startIndex < input.Length)
    {
        int index = input.IndexOf(separator, startIndex);
        if (index == -1)
        {
            // Добавляем оставшуюся часть строки
            result.Add(input.Substring(startIndex));
            break;
        }

        string part = input.Substring(startIndex, index - startIndex);
        if (options != StringSplitOptions.RemoveEmptyEntries || part.Length > 0)
            result.Add(part);

        startIndex = index + sepLength;
    }

    return result.ToArray();
}

Использование:

string data = "Привет||мир||C#";
string[] parts = SplitByString(data, "||", StringSplitOptions.RemoveEmptyEntries);

Рекомендация

Если ваш проект уже использует .NET Core 2.0+ или .NET 5+, просто вызывайте data.Split("||") — это самое короткое и читаемое решение. Для .NET Framework используйте перегрузку с массивом строк: data.Split(new[] { "||" }, StringSplitOptions.None). Регулярные выражения применяйте только когда нужна сложная логика (например, разделение по нескольким разным строкам-разделителям или с игнорированием регистра).

<<>>

Использование LINQ и string.Split() с символьным разделителем (если разделитель состоит из одного уникального символа)

Иногда можно обойтись без разбиения по строке, если найти символ, который гарантированно не встречается в данных, и заменить им нужный разделитель. Например, если ваш разделитель "||", можно заменить его на символ '|' (одиночный), но это сработает только если в исходных данных нет одиночных '|'.

string data = "Привет||мир||C#";
string[] parts = data.Replace("||", "|").Split('|');

Этот подход опасен, если ваш разделитель может содержать символы, которые есть в данных. Лучше использовать string.Split() с массивом строк, как описано в первом ответе.

Использование string.Split() с StringSplitOptions.TrimEntries (только .NET 5+)

В .NET 5+ появилась опция StringSplitOptions.TrimEntries, которая автоматически обрезает пробелы у каждого элемента:

string data = "Привет || мир || C#";
string[] parts = data.Split(
    new string[] { "||" },
    StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
// Результат: ["Привет", "мир", "C#"]

Это удобно, если в данных есть лишние пробелы вокруг разделителей. Комбинируйте флаги через | для получения нужного поведения.