JavaScript Tips | 文字列ユーティリティ:業務用 - 改行コード統一

JavaScript JavaScript
スポンサーリンク

何をしたいユーティリティか:「改行コード統一」

ここでの「改行コード統一」は、
バラバラな改行コード(\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 "";
}
JavaScript

nullundefined が来たときにエラーにせず、
「改行のない空テキスト」として扱うようにしています。

業務コードでは、「とりあえず落ちない」ことが大事な場面も多いので、
ここでガードしておくと安心です。

まずは文字列に変換する

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" になってしまいます。

なので、

  1. \r\n\n
  2. 残った単独の \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";
}
JavaScript

target"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

を置き、

「外から来たテキスト・ファイルに触る前には、必ず“改行コード統一ユーティリティ”を通す」

というルールを作ってみてください。
それだけで、あなたのシステムのテキスト処理は、環境依存に振り回される状態から、
意図と一貫性を備えた「業務レベルのテキスト設計」に変わっていきます。

タイトルとURLをコピーしました