何をしたいユーティリティか:「改行コード統一」
ここでの「改行コード統一」は、
バラバラな改行コード(\n, \r\n, \r)が混ざったテキストを、指定した形式にそろえる処理です。
Windows 由来のファイルは \r\n、
Unix / macOS / Linux は \n、
古い Mac は \r、
ブラウザや外部システムから来たテキストは、これらが混在していることがあります。
このまま扱うと、
- 行数カウントが合わない
- 差分(diff)がぐちゃぐちゃになる
- 比較やテストが安定しない
といった問題が起きます。
だからこそ、「まず改行コードを統一してから処理する」ユーティリティを用意しておくと、業務でかなり効きます。
改行コードの種類をざっくり整理する
よく出てくる 3 種類
改行コードは、主にこの 3 つです。
\n(LF)
Unix / macOS / Linux、Web の世界の標準的な改行。
\r\n(CRLF)
Windows の標準的な改行。
\r(CR)
古い Mac などで使われていた改行。今でもたまに混ざることがある。
実務では、「外から来るテキストは何でもあり」「中で扱うときは 1 種類に統一」という方針にするのが現実的です。
一番シンプルな「LF に統一」ユーティリティ
normalizeNewlinesToLF の実装
まずは、内部表現として一番扱いやすい \n(LF)に統一する関数を作ります。
function normalizeNewlinesToLF(text) {
if (text == null) {
return "";
}
let str = String(text);
str = str.replace(/\r\n/g, "\n");
str = str.replace(/\r/g, "\n");
return str;
}
JavaScript重要なポイントをかみ砕いて説明する
null / undefined を空文字にそろえる
if (text == null) {
return "";
}
JavaScriptnull や undefined が来たときにエラーにせず、
「改行のない空テキスト」として扱うようにしています。
業務コードでは、「とりあえず落ちない」ことが大事な場面も多いので、
ここでガードしておくと安心です。
まずは文字列に変換する
let str = String(text);
JavaScript数値や他の型が来ても、ここで文字列にしてしまえば、
あとは「文字列としての改行コード」だけを気にすればよくなります。
置換の順番が大事
str = str.replace(/\r\n/g, "\n");
str = str.replace(/\r/g, "\n");
JavaScriptここ、順番がとても重要です。
先に \r\n を \n に変えています。
もし先に \r を \n にしてしまうと、"\r\n" が "\n\n" になってしまいます。
なので、
\r\n→\n- 残った単独の
\r→\n
という順番で処理するのが正解です。
実際の動きを例で確認する
normalizeNewlinesToLF("a\r\nb\r\nc");
// "a\nb\nc"
normalizeNewlinesToLF("a\nb\nc");
// "a\nb\nc"(もともと LF ならそのまま)
normalizeNewlinesToLF("a\rb\rc");
// "a\nb\nc"
normalizeNewlinesToLF(null);
// ""
JavaScriptこれで、「どんな改行が混ざっていても、とりあえず LF にそろえる」ことができます。
出力形式を選べる汎用版ユーティリティ
ターゲットを指定できる normalizeNewlines
業務では、「内部では LF、ファイル出力時は CRLF」など、
場面によって欲しい改行コードが変わることがあります。
そこで、「ターゲットの改行コードを指定できる」汎用版を作ります。
function normalizeNewlines(text, target = "LF") {
if (text == null) {
return "";
}
let str = String(text);
str = str.replace(/\r\n/g, "\n");
str = str.replace(/\r/g, "\n");
let newline = "\n";
if (target === "CRLF") {
newline = "\r\n";
} else if (target === "CR") {
newline = "\r";
}
if (newline !== "\n") {
str = str.replace(/\n/g, newline);
}
return str;
}
JavaScript汎用版の重要ポイントを深掘りする
まずは「一度 LF にそろえる」
str = str.replace(/\r\n/g, "\n");
str = str.replace(/\r/g, "\n");
JavaScriptここまでは先ほどと同じです。
一旦すべてを LF に統一することで、
「入力側のバリエーション」を気にしなくてよくなります。
ターゲットに応じて改行コードを決める
let newline = "\n";
if (target === "CRLF") {
newline = "\r\n";
} else if (target === "CR") {
newline = "\r";
}
JavaScripttarget は "LF" | "CRLF" | "CR" の 3 種類を想定しています。
デフォルトは "LF" です。
必要なら LF をターゲットに置き換える
if (newline !== "\n") {
str = str.replace(/\n/g, newline);
}
JavaScriptターゲットが LF のときは、すでに LF に統一済みなので何もしません。
ターゲットが CRLF や CR のときだけ、LF を置き換えます。
実際の動きを例で確認する
const text = "a\r\nb\nc\rd";
normalizeNewlines(text, "LF");
// "a\nb\nc\nd"
normalizeNewlines(text, "CRLF");
// "a\r\nb\r\nc\r\nd"
normalizeNewlines(text, "CR");
// "a\rb\rc\rd"
JavaScript入力がどんな混在状態でも、
出力は「指定した形式の改行コードだけ」にそろっているのが分かります。
実務での使いどころ
テキスト比較・テストコードでの安定化
外部システムから受け取ったテキストを、
期待値と比較するテストを書くとき、
改行コードの違いだけでテストが落ちるのはもったいないです。
const actual = normalizeNewlines(receivedText, "LF");
const expected = "line1\nline2\nline3";
expect(actual).toBe(expected);
JavaScriptこのように、「比較前に改行コードを統一する」だけで、
環境差(Windows / macOS / Linux)によるテストの不安定さをかなり減らせます。
ファイル出力時のフォーマット統一
業務で CSV やログファイルを出力するとき、
「Windows で開く前提だから CRLF にしたい」
「サーバ間連携で LF に統一したい」
といった要件がよくあります。
その場合は、
const body = rows.join("\n"); // まずは LF で組む
const fileContent = normalizeNewlines(body, "CRLF"); // 出力時に CRLF に変換
JavaScriptのように、「内部は LF、外に出すときだけ変換」というパターンにしておくと、
扱いやすく、かつ要件も満たせます。
エディタや OS の違いを吸収する
チームメンバーが Windows と macOS で混在していると、
「誰が保存したかによって改行コードが変わる」問題が起きがちです。
Git の設定やエディタの設定である程度は制御できますが、
アプリケーション側でも「入力テキストは normalizeNewlines でそろえる」と決めておくと、
予期せぬ差分やバグを減らせます。
少し手を動かして感覚をつかむ
コンソールで、次のようなコードを実際に打ってみてください。
const mixed = "a\r\nb\nc\rd";
normalizeNewlinesToLF(mixed);
normalizeNewlines(mixed, "LF");
normalizeNewlines(mixed, "CRLF");
normalizeNewlines(mixed, "CR");
JavaScriptそれぞれの結果を JSON.stringify で確認すると、
どの文字が \n で、どこが \r\n になっているかが分かりやすいです。
JSON.stringify(normalizeNewlines(mixed, "CRLF"));
// "\"a\\r\\nb\\r\\nc\\r\\nd\""
JavaScriptそのうえで、自分のプロジェクトに
export function normalizeNewlinesToLF(...) { ... }
export function normalizeNewlines(...) { ... }
JavaScriptを置き、
「外から来たテキスト・ファイルに触る前には、必ず“改行コード統一ユーティリティ”を通す」
というルールを作ってみてください。
それだけで、あなたのシステムのテキスト処理は、環境依存に振り回される状態から、
意図と一貫性を備えた「業務レベルのテキスト設計」に変わっていきます。
