動くコード図鑑技術記事現場の渡り方キャリア論すべての記事About
技術記事

C# の String.Split と String.Join 使い分け3パターン — CSV 行の分解・結合を業務SEが安全に書く

バイブス父さん
現役の業務SE
2026年7月5日10 min read
C# の String.Split と String.Join 使い分け3パターン — CSV 行の分解・結合を業務SEが安全に書く

みなさんこんにちは!ヒロポンです!

「カンマ区切りの文字列を配列に分けたい」「逆に配列をカンマでつなぎたい」。

CSV の取り込みとか連携データの整形をやってると、しょっちゅう降ってくるやつですよね。

String.SplitString.Join を使えば一発…なんですが、ここに地味な罠が潜んでます。件数が合わないとか、住所が途中で割れるとか。

今回はC# 文字列 分割の基本を3パターン、結合とセットで、コピペで動く形にまとめました。最後に「Split で済む線」と「ここから先は本格 CSV パーサ」の線引きも引いておきます。

結論: この3パターン+ Join を押さえれば足りる

先に答えから。csv"田中,1000,東京" とすると、こんな感じ。

using System;

class Program
{
    static void Main()
    {
        string csv = "田中,1000,東京";

        // パターン1: 単一区切りで分割
        string[] cols = csv.Split(',');
        Console.WriteLine(cols[0]);            // 田中
        Console.WriteLine(cols.Length);        // 3

        // パターン2: 空要素を捨てる (末尾カンマ対策)
        string[] clean = "a,,b,,c,".Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        Console.WriteLine(string.Join("/", clean));   // a/b/c

        // パターン3: 複数の区切り文字・改行をまとめて分割
        string[] tokens = "a,b;c\nd".Split(new[] { ',', ';', '\n' }, StringSplitOptions.RemoveEmptyEntries);
        Console.WriteLine(string.Join("/", tokens));  // a/b/c/d

        // 結合: 配列を区切り文字でつなぐ (Split の逆)
        string joined = string.Join(",", cols);
        Console.WriteLine(joined);             // 田中,1000,東京
    }
}

実行結果(.NET 9 で実機確認):

String.Split / Join の3パターン+結合の実行結果

これで業務でぶつかる分割・結合の8割はカタがつきます。

残りの2割が罠。末尾カンマと、クォート囲み CSV ですね。後半でまるっと潰します。

パターン1: 単一区切りで分割する(Split の基本)

一番シンプルなやつ。区切り文字を1つ渡すだけ。

string[] cols = "田中,1000,東京".Split(',');
// cols[0]="田中", cols[1]="1000", cols[2]="東京"

Split(',') で文字(char)を1つ渡す形。コピペで一番使うのはこれです。

ただ注意が1つあって。Split で読んだ各要素は全部 stringなんですよね。

cols[1]"1000" は数値じゃなくて文字列。計算するなら int.Parseint.TryParse でキャストが要ります。

このへんは C# TryParse の正解 でまとめてるので、別タブで開いて後で読んでくださいな。

パターン2: 空要素を捨てる(RemoveEmptyEntries)

ここがいい感じに効くやつ。StringSplitOptions.RemoveEmptyEntries を付けると、空の要素を勝手に捨ててくれます!!

string data = "a,,b,,c,";

// 空要素も全部返ってくる
string[] raw = data.Split(',');          // ["a","","b","","c",""] → 6個

// 空要素を捨てる
string[] clean = data.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
// ["a","b","c"] → 3個

連続した区切りや末尾の区切りで「空の項目」が混ざるデータに効きます。

これを知らないと、後の罠1で件数がズレる。覚えておいて損なし。

💡 .NET Framework 4.7.2 を使ってる現場向け注意: Split(',', StringSplitOptions...) のように char とオプションを直接渡す書き方は .NET Core 2.1 以降専用です。.NET Framework だと存在しないので、上のように Split(new[] { ',' }, ...)配列で渡す書き方にしておくと、新旧どっちでも動きます。

パターン3: 複数の区切り文字・改行をまとめて分割する

カンマだけじゃなく、セミコロンや改行も区切りに混ぜたい時。char[] で複数渡せます。

string mixed = "a,b;c\nd";
char[] seps = { ',', ';', '\n' };

string[] tokens = mixed.Split(seps, StringSplitOptions.RemoveEmptyEntries);
// ["a","b","c","d"]

改行は '\n' を入れればOK。Windows 改行(CRLF)が混ざるなら '\r' も足しておくと安全です。

で、結合は String.Join。分割の逆で、配列を区切り文字でつなぎます。

string[] arr = { "田中", "1000", "東京" };
string line = string.Join(",", arr);   // "田中,1000,東京"

Join の第1引数が区切り文字、第2引数が配列。こんな感じで Split と対で覚えておくと、整形処理がスッと書けます。

ハマりポイント①: 末尾カンマで空要素が増えて件数が合わない

正直に言うと、俺もこれでデータ件数が合わずに小一時間詰まったことがあります。

「3項目のはずが4項目で返ってくる」。ん?なんで増えた??原因は末尾のカンマでした。

string line = "a,b,c,";   // 末尾にカンマ
string[] p = line.Split(',');
// p.Length == 4   ← 末尾の "" も1要素として数える

Split空文字も律儀に1要素として返すので、末尾カンマがあると要素数が1つ増える。

件数でループやバリデーションを回してると、ここで静かにズレるんですよね。エラーも出ないから余計にタチが悪い。

対処は2つ。期待する形に合わせて選んでください。

  • 空項目を捨てていいなら StringSplitOptions.RemoveEmptyEntries
  • 列の位置(何番目が何の項目か)が大事なら、捨てずに Length を検証してデータ不正として弾く

教訓はシンプルで、Split の結果の件数を信じる前に、Length を1回見る。これだけで件数ズレの事故がガクッと減ります。

ハマりポイント②: ダブルクォート囲みの CSV は Split で壊れる

これが一番こわい線引き。値の中に区切り文字が入っている CSVを、Split(',') で割ると壊れます。

string row = "山田,\"東京都, 千代田区\",30";
string[] bad = row.Split(',');
// bad.Length == 4
// bad[1]="\"東京都", bad[2]=" 千代田区\"" ← 住所が真っ二つ

"東京都, 千代田区" はダブルクォートで囲って「ここはひとかたまり」と表現してるのに、Split はクォートを理解しない。中のカンマでも容赦なく割ります。

住所や備考欄でよく踏むやつ。え、これ Split で割れるの??割れるんです。

ここが Split の限界。線引きはこう考えてます。

  • 自分が作る固定フォーマット(区切り文字が値に絶対入らないと分かってる)→ Split でOK
  • 外部からもらう CSV(クォート囲み・エスケープ・改行入りフィールドがありうる)→ Split は使わず、本格的な CSV パーサを使う

.NET なら TextFieldParserMicrosoft.VisualBasic.FileIO 名前空間・標準で使える)か、CsvHelper(NuGet)が定番です。

「業務データの CSV を Split で読んでる」のを見かけたら、それは時限爆弾だと思ってください。

現場メモ: 分割で時間を溶かさないために

手段ごとの向き不向きを1枚にまとめておきます。「これ Split でいいんだっけ?」と迷ったら、ここを見てください。

文字列分割の手段(String.Split / Split+RemoveEmptyEntries / 本格CSVパーサ)を、単純区切り・空要素処理・複数区切り・クォート囲み・フィールド内改行・手軽さの観点で比較した表

俺の現場ルールはシンプルです。自分が出力を握ってるデータは Split、他人からもらう CSV はパーサ

この線引きを最初に決めておくと、後で「住所が割れてる」みたいな事故に呼ばれずに済みます。

まとめ

要点はこれだけ。

  • 基本は Split(',')、空要素を捨てたいなら Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries)
  • 複数区切りは char[] で渡す。結合は string.Join(",", 配列) が対
  • 末尾カンマで件数が増えるので、Length を1回見る
  • クォート囲み・改行入りの外部 CSV は Split で壊れる → 本格パーサに切り替える

C# の文字列まわりは細かい挙動が多いので、言語仕様系の解説書を1冊持っておくと、この手の「なんで?」を調べる時間がまるっと浮きます。

このパターン集、ブックマークして使ってください。

よくある質問

Q1. Split の結果が string[] で返るのはなぜ?数値で欲しいです。

Split は文字列を文字列に分けるメソッドなので、要素は必ず string です。数値で扱いたいなら int.Parseint.TryParse でキャストしてください。不正値が混じる可能性があるデータなら、例外で落ちない TryParse のほうが安全です。

Q2. Split(',') と Split(new[]{','}) はどう違いますか?

結果は同じですが、StringSplitOptions(空要素除去など)を付けたい時に書き方が変わります。char を直接渡すオプション付きオーバーロードは .NET Core 2.1 以降専用なので、.NET Framework でも動かすなら new[] { ',' } の配列形で書くのが無難です。

Q3. 空白(スペース区切り)で分割するには?

text.Split(' ') で区切れますが、連続スペースだと空要素が残ります(引数なしの text.Split() も空白では区切りますが、空要素は除去されません)。空要素を捨てたいなら text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) を使ってください。タブや改行も含めた空白全般でまとめて区切りつつ空要素も捨てたいなら、text.Split((char[])null, StringSplitOptions.RemoveEmptyEntries) が便利です。

次に読むべき記事

以上!

同じデータ件数ズレで詰まった人いたら、どんどんシェア待ってるぜ!!


執筆者

バイブス父さん — 業務 SE 7 年 (SIer 正社員 2 / フリーランス 5)。 現職は SEO 直轄部の AI アドバイザー兼 PL、 副業で中小 SIer の CTO。 SIer の正社員からフリーランスに転じ、 複数のエージェント経由で案件を回してきた経験ベースで「業務 SE 視点」 の技術 + キャリア記事を書いています。

🐦 X: @hiro_progra0524 (日々の現場メモ更新中)
📝 About Me で経歴詳細を見る

この記事のコードと手順は ぜんぶ動作検証済み。 安心して現場で試してくれ。
バイブス父さん

現役の業務SE。C# / SQL Server 保守の現場から、コードも人もキャリアも全部書く。 実体験ベース。

運営者について