JavaScriptでテキストデータを扱う際、避けて通れないのが改行コードの処理です。
プラットフォームによって改行コードが異なるため、システム間でのデータ連携やユーザー入力の加工において、意図しない挙動を防ぐための制御が欠かせません。
かつては複雑な正規表現を駆使してすべての改行を置換していましたが、現代のJavaScriptではreplaceAllメソッドなどの登場により、より直感的で安全な実装が可能になっています。
本記事では、2026年現在の標準的な手法に基づき、改行コードの判定・変換・削除といった実務で多用するテクニックを詳しく解説します。
改行コードの基本知識とOSによる違い
プログラムの世界で「改行」を表現するコードには、主に3つの種類が存在します。
1つ目は、UNIX系OSや現在のmacOSで標準的に使用されている「LF(Line Feed)」です。
エスケープシーケンスでは\nと表記され、モダンな開発環境では最も一般的に利用される形式です。
2つ目は、Windows環境で伝統的に使われている「CRLF(Carriage Return + Line Feed)」です。
これは\r\nという2文字のコードで1つの改行を表現するため、処理を誤ると空行が増えたり、文字数がずれたりする原因となります。
3つ目は、古いMac OS(バージョン9以前)で使用されていた「CR(Carriage Return)」ですが、現代のWeb開発で遭遇する機会は極めて稀です。
しかし、古いシステムからエクスポートされたテキストデータを扱う場合には、稀に混入している可能性があるため注意が必要です。
Webアプリケーションの開発においては、ユーザーがどのOSからアクセスしてくるか予測できないため、すべての改行コードを適切に正規化することが求められます。
replaceAllメソッドによるシンプルな置換
ECMAScript 2021以降、JavaScriptにはreplaceAllメソッドが標準搭載されており、現在ではすべての主要なブラウザやNode.js環境で利用可能です。
従来のreplaceメソッドでは、文字列を指定した場合に最初に見つかった1箇所しか置換されませんでしたが、replaceAllを使えばすべての該当箇所を一括で置換できます。
replaceAllを用いた基本的な改行変換
例えば、Windows形式の改行(CRLF)をすべてLinux形式(LF)に統一したい場合は、以下のように記述します。
// Windows形式の改行を含む文字列
const sourceText = "JavaScript\r\nProgramming\r\n2026";
// CRLF (\r\n) をすべて LF (\n) に置換
const normalizedText = sourceText.replaceAll("\r\n", "\n");
console.log(normalizedText);
JavaScript
Programming
2026
この手法は、置換対象が明確に決まっている場合に非常に有効です。
しかし、replaceAllに文字列を渡すと、「\r\n」には対応できても「単体の\n」や「単体の\r」が混在している場合には対応できません。
そのため、複数の改行コードが混在する可能性がある複雑なテキスト処理では、次に紹介する正規表現との組み合わせが必要になります。
正規表現を用いた高度な改行制御
不特定多数のユーザーが入力するテキストや、外部APIから取得したデータには、複数の改行コードが入り混じっていることがよくあります。
このようなケースでは、正規表現を用いることで、どんな改行コードでも一括でキャッチして制御できるようになります。
すべての改行コードにマッチする正規表現
もっとも堅牢な正規表現パターンは /\r\n|\r|\n/g です。
このパターンは「CRLF、CR、LFのいずれか」にマッチし、gフラグによって文字列全体を検索します。
// 複数の改行コードが混在する汚れたデータ
const messyText = "Line1\nLine2\r\nLine3\rLine4";
// すべての改行コードを「LF」に統一する
const unifiedText = messyText.replace(/\r\n|\r|\n/g, "\n");
console.log("統一後:", JSON.stringify(unifiedText));
統一後: "Line1\nLine2\nLine3\nLine4"
上記のコードでは、replaceメソッドに正規表現を渡しています。
正規表現にグローバルフラグ(g)を付けることで、replaceであってもすべての箇所を置換対象にできます。
現代のJavaScriptエンジンでは、この正規表現による一括置換は非常に高速に動作するため、パフォーマンス面の懸念はほとんどありません。
実践的な活用シーン
改行コードの制御が必要になる具体的な開発シーンを見ていきましょう。
テキストエリア入力の正規化
HTMLの<textarea>から取得した値は、ブラウザによって改行コードの扱いが異なる場合があります。
サーバーに送信する前に改行を統一しておかないと、データベース内での文字数カウントや検索に支障が出ることがあります。
const textarea = document.querySelector("#user-comment");
const rawValue = textarea.value;
// 送信前にLFへ統一し、前後の不要な空白を削除する
const cleanValue = rawValue.replace(/\r\n|\r|\n/g, "\n").trim();
console.log("送信データ:", cleanValue);
このように、入力値のバリデーションやサニタイズの一環として改行の正規化を組み込むのが一般的です。
改行をHTMLの<br>タグに変換する
JavaScriptで取得したテキストをブラウザ上のHTML要素に表示する場合、改行コードは無視されてしまいます。
これを正しく改行して表示するためには、改行コードを<br>タグに変換する必要があります。
const plainText = "こんにちは。\n今日は良い天気ですね。";
// 改行コードを <br> タグに変換
const htmlString = plainText.replace(/\r\n|\r|\n/g, "<br>");
// DOMに挿入(innerHTMLを使用する場合はXSSに注意)
const displayElement = document.getElementById("output");
displayElement.innerHTML = htmlString;
ただし、innerHTMLを使用する際はクロスサイトスクリプティング(XSS)への対策を忘れないでください。
信頼できないユーザーからの入力を扱う場合は、先にエスケープ処理を行うか、CSSのwhite-space: pre-wrap;を利用して改行コードをそのまま表示させる方法を検討してください。
テキストを1行ずつの配列に分割する
ログファイルの解析やCSVデータの処理などで、テキストを「行単位」でループ処理したいケースがあります。
この場合、splitメソッドに正規表現を渡すことで、改行コードの種類を問わず正確に行を分割できます。
const multiLineText = "Item1\nItem2\r\nItem3";
// 改行コードで分割して配列にする
const rows = multiLineText.split(/\r\n|\r|\n/);
console.log("行数:", rows.length);
rows.forEach((row, index) => {
console.log(`${index + 1}行目: ${row}`);
});
行数: 3
1行目: Item1
2行目: Item2
3行目: Item3
単純に split("\n") としてしまうと、CRLFが含まれていた場合に各行の末尾に不可視の \r が残ってしまうため注意してください。
正規表現で分割することで、そうした不要な制御文字を綺麗に取り除くことができます。
2026年における最新の注意点
Web標準の進化に伴い、JavaScriptにおける文字列処理のパフォーマンスは向上し続けています。
しかし、数MBを超えるような巨大なテキストデータを扱う際には、依然としてメモリ消費量に注意を払う必要があります。
大規模なデータを処理する場合、一度にすべての改行を置換して新しい文字列を生成すると、一時的に大きなメモリを消費します。
そのような場面では、ReadableStreamなどを用いてデータをチャンク(断片)ごとに処理し、ストリーム上で逐次的に改行を制御する手法が推奨されます。
また、国際化が進む中で、絵文字や特殊な言語の文字が改行と組み合わさるケースも増えています。
通常の改行コード置換であれば大きな問題にはなりませんが、文字単位での高度な加工を行う場合は、Intl.Segmenterを使用して「書記素(Grapheme)」単位でテキストを扱うことも検討すべきです。
まとめ
JavaScriptにおける改行コードの制御は、一見単純に見えて、クロスプラットフォーム対応において非常に重要な役割を果たします。
replaceAllメソッドはコードの可読性を高める強力な武器となりますが、多様なOS由来のデータに対応するためには、今なお正規表現 /\r\n|\r|\n/g を活用した処理がもっとも確実です。
「データの入力口」でしっかりと正規化を行い、内部処理では統一された改行コード(一般的にはLF)を使用することが、バグの少ない堅牢なプログラムへの第一歩です。
今回紹介したテクニックを活用し、ユーザーの環境に依存しない、安定したテキスト処理を実装してください。
