2024-08-09 (金)
[C#] 文字列を改行コードで1行ずつに分割する方法
LF, CRLF などの改行コードで1行ずつの文字列を分割して取得する方法です。
環境
- .NET 8.0.7 (SDK 8.0.303)
- C# 12.0
- Visual Studio 2022 Version 17.10.5
- Windows 11 Pro 23H2 22631.3880
EnumerateLines() で1行ずつ列挙する
MemoryExtensions.EnumerateLines() を使用する例です。.NET 6 以降で利用可能です。
string[]
にする必要がなければ、foreach
で処理できます。
string text = GetSampleText();
foreach (var line in text.AsSpan().EnumerateLines())
{
// line が ReadOnlySpan<char> なので、string にしたければ ToString() で変換
Console.WriteLine(line.ToString());
}
EnumerateLines() で分割して配列にする
次に、string[]
にする必要がある場合です。
public static string[] SplitLines(ReadOnlySpan<char> span)
{
using var builder = new ValueArrayBuilder<string>();
foreach (var element in span.EnumerateLines())
{
builder.Add(element.ToString());
}
return builder.ToArray();
}
ValueArrayBuilder
は List<string>
に置き換えても問題ありません。
詳しくは以下の記事を参照してください。
[C#] ArrayPool を使用して ToArray のアロケーションを1回にする方法
一般的には List<T>
を使用して要素を追加して行き、最後に ToArray()
することで配列を作成します。
この方法では、最後の配列以外に作業用のヒープメモリ確保が発生してしまいます。
プールと構造体を使用することで、最後の完成した配列に対して1回のみメモリ確保する実装例です。
Split() で分割する
String.Split を使用する例です。
private static readonly string[] NewLineStrings = ["\r\n", "\n"];
public static string[] SplitLines(string value)
{
return text.Split(NewLineStrings, StringSplitOptions.None);
}
CRLF
と LF
が混在していても対応できるように、両方指定しています。ただし、それ以外の改行コードは考慮していません。
💡 前述の EnumerateLines() は、CRLF
と LF
以外の改行コードにも対応しています。
関連記事
新着記事