Обновление: см. здесь для альтернативного / асинхронного решения.
Это прекрасно работает и работает быстрее, чем Regex:
input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
Важно иметь "\r\n"
первым в массиве, чтобы он воспринимался как один разрыв строки. Вышеприведенное дает те же результаты, что и любое из этих решений Regex:
Regex.Split(input, "\r\n|\r|\n")
Regex.Split(input, "\r?\n|\r")
За исключением того, что Regex оказывается примерно в 10 раз медленнее. Вот мой тест:
Action<Action> measure = (Action func) => {
var start = DateTime.Now;
for (int i = 0; i < 100000; i++) {
func();
}
var duration = DateTime.Now - start;
Console.WriteLine(duration);
};
var input = "";
for (int i = 0; i < 100; i++)
{
input += "1 \r2\r\n3\n4\n\r5 \r\n\r\n 6\r7\r 8\r\n";
}
measure(() =>
input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
);
measure(() =>
Regex.Split(input, "\r\n|\r|\n")
);
measure(() =>
Regex.Split(input, "\r?\n|\r")
);
Выход:
00: 00: 03,8527616
00: 00: 31,8017726
00: 00: 32,5557128
и вот метод расширения :
public static class StringExtensionMethods
{
public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
{
return str.Split(new[] { "\r\n", "\r", "\n" },
removeEmptyLines ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None);
}
}
Использование:
input.GetLines() // keeps empty lines
input.GetLines(true) // removes empty lines