Как разбить строку на массив строк по символам новой строки в C#?
Использование String.Split с правильным набором разделителей
Проблема, с которой вы столкнулись, типична для начинающих разработчиков. Дело в том, что разные операционные системы используют разные символы для обозначения конца строки:
- Windows:
\r\n(CR+LF) - Unix/Linux/macOS:
\n(LF) - Старые Mac:
\r(CR)
Поэтому разбивка только по одному символу \n приводит к тому, что символ \r остаётся в конце строк. Вот правильное и элегантное решение:
string text = "Первая строка\r\nВторая строка\nТретья строка\rЧетвёртая строка";
// Вариант 1: Использование массива разделителей
string[] lines = text.Split(
new[] { "\r\n", "\n", "\r" },
StringSplitOptions.None
);
// Вариант 2: С удалением пустых строк (если есть пустые строки)
string[] lines2 = text.Split(
new[] { "\r\n", "\n", "\r" },
StringSplitOptions.RemoveEmptyEntries
);
foreach (string line in lines)
{
Console.WriteLine($"'{line}'");
}
Лучший способ: Использование StringReader
Начиная с .NET Framework 2.0, существует более правильный способ — класс StringReader. Он автоматически обрабатывает все варианты переносов строк:
using System.IO;
string text = "Первая строка\r\nВторая строка\nТретья строка\rЧетвёртая строка";
List<string> linesList = new List<string>();
using (StringReader reader = new StringReader(text))
{
string line;
while ((line = reader.ReadLine()) != null)
{
linesList.Add(line);
}
}
string[] lines = linesList.ToArray();
Самый современный способ (.NET 6+)
Начиная с .NET 6, появился удобный метод SplitLines(), который делает всё за вас:
string text = "Первая строка\r\nВторая строка\nТретья строка\rЧетвёртая строка";
string[] lines = text.SplitLines();
Важно: Метод SplitLines() доступен только в .NET 6 и новее. Если вы используете более старую версию, используйте StringReader.
Что выбрать?
- Если вы используете .NET 6+: используйте
SplitLines()— это самый простой и читаемый вариант. - Если у вас старая версия .NET: используйте
StringReader— он надёжно обрабатывает все варианты переносов и не оставляет лишних символов. - Если нужна максимальная производительность: используйте
String.Splitс массивом разделителей, но помните, что этот вариант менее читаемый.
В вашем случае я рекомендую StringReader, так как он не зависит от версии .NET и гарантированно корректно обрабатывает любой текст, независимо от того, на какой платформе он был создан.
Альтернативный подход: Регулярные выражения
Если вам нужно больше контроля над процессом разбивки, можно использовать регулярные выражения. Это особенно полезно, если в строках могут быть нестандартные разделители или вы хотите дополнительно обработать текст:
using System.Text.RegularExpressions;
string text = "Первая строка\r\nВторая строка\nТретья строка\rЧетвёртая строка";
// Разбиваем по всем возможным комбинациям переносов строк
string[] lines = Regex.Split(text, @"\r\n|\n|\r");
// С удалением пустых строк
string[] lines2 = Regex.Split(text, @"\r\n|\n|\r")
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
foreach (string line in lines)
{
Console.WriteLine($"'{line}'");
}
Плюсы: Гибкость — можно легко изменить шаблон для обработки специфических случаев (например, если нужно игнорировать переносы внутри кавычек).
Минусы: Меньшая производительность по сравнению с StringReader или SplitLines(), а также более сложный синтаксис для начинающих.
Если производительность не критична (например, вы обрабатываете небольшие объёмы данных), этот подход вполне рабочий. Для больших файлов лучше использовать StringReader.