【JavaScript】replaceAllとは?一括置換の方法を初心者向けにわかりやすく解説
はじめに
JavaScriptで文字列を操作するとき、特定の単語や記号をまとめて置換したい場面は意外と多いかもしれません。
たとえば、複数個所に同じ誤字が含まれていたり、特定のキーワードをまとめて別の表記に変えたいケースです。
これまでJavaScriptにはreplace
メソッドが用意されていましたが、1つの文字列に対して最初に見つかったものしか置換されませんでした。
そのため、同じ単語が複数回出現する場合、正規表現を使ったり、ループを回したりといった工夫が必要でした。
ところが、replaceAll
メソッドが登場したことで、すべての同一パターンをまとめて置換することが簡単になりました。
この記事を読むとわかること
- replaceAllメソッドの基本的な使い方
- replaceメソッドとの違いと注意点
- 正規表現を利用した高度な置換方法
- 実務で役立つ具体的なサンプルコード
- 置換時のパフォーマンスやエラー回避のポイント
replaceAllとは何か
replaceAll
はJavaScriptで文字列を一括置換するためのメソッドです。
文字列の中から指定したパターン(文字列あるいは正規表現)に合致するすべての箇所を探し、任意の別の文字列へまとめて置き換えてくれます。
これによって、たとえば大量のテキストデータの中で特定の文字を一度に変更したい時など、従来のreplace
よりも効率的で読みやすいコードを実現しやすくなります。
一部だけ置換されて残ってしまう不安が減り、コードの見通しもシンプルに保ちやすくなるのが特徴です。
文字列操作における重要性
文字列の編集は、どんなプログラムでも頻繁に行われる処理のひとつです。
ユーザーからの入力テキストの整形や、APIレスポンスのフォーマット変更、ログの解析など、多岐にわたる作業で文字列操作が必要になるでしょう。
これらの場面で複雑なロジックを書くより、簡潔に必要な変更を加えられれば、バグの発生リスクを抑えやすくなります。
それだけでなく、ソースコードの可読性を高める効果も期待できますので、チーム開発や長期的な保守の観点からも役立つアプローチと言えます。
replaceとreplaceAllの違い
replace
は最初に見つかったマッチだけが置換されます。
同じ文字列が複数回登場しても、標準的な使い方では最初の1箇所しか変換されないのが特徴です。
一方で、replaceAll
は名前の通り、対象文字列内でパターンに合致するすべての箇所を一気に置換します。
そのため、コード量を減らしたり、意図し忘れを防いだりする上で強みを発揮します。
ただし、正規表現を使う場合には、replaceAll
に正規表現を渡すときに少し注意点があるので、後ほど詳しく解説します。
サンプルコードの比較
ここではごく単純な例として、文字列中のapple
をorange
に置き換えるケースを見てみます。
replace
では以下のように1つ目のapple
しか変換されません。
const text = "apple banana apple"; const replaced1 = text.replace("apple", "orange"); console.log(replaced1); // 結果: "orange banana apple"
続いて、replaceAll
を使う例です。
こちらはすべてのapple
が置き換えられます。
const replaced2 = text.replaceAll("apple", "orange"); console.log(replaced2); // 結果: "orange banana orange"
両者を比べると、意図通りにすべてのapple
を変更したいときはreplaceAll
が便利であることがわかります。
replaceAllの基本的な使い方
replaceAll
の構文自体はreplace
とよく似ています。
第一引数に置換対象、第二引数に置換後の文字列を指定するだけです。
ただし、もし第一引数を正規表現で指定する場合、/pattern/g
のようにグローバルフラグを付与しておかないとエラーになるケースがあります。
この点が従来のreplace
とはやや異なる部分ですので注意が必要です。
単純置換の例
まずは、最もシンプルなケースとして、文字列を指定して一括置換する例を示します。
たとえば、大文字の"HELLO"をすべて小文字の"hello"に変えてみましょう。
const greeting = "HELLO everyone, HELLO world"; const result = greeting.replaceAll("HELLO", "hello"); console.log(result); // 出力: "hello everyone, hello world"
このように、ターゲットとして単純な文字列を与えるだけで手軽に使えます。
特に難しい設定も不要で、読みやすいコードになるでしょう。
正規表現との組み合わせ
文字列ではなく、正規表現を用いると、より柔軟な置換が可能になります。
たとえば、区切り文字が不揃いなデータを整形するときなどに重宝します。
const messyData = "A|B,C;D"; const replacedData = messyData.replaceAll(/[|,;]/g, ":"); console.log(replacedData); // 出力: "A:B:C:D"
ここで使用している正規表現/[|,;]/g
は、パイプ・カンマ・セミコロンのいずれかにマッチします。
それをまとめてコロンに変えることで、どんな区切り文字であっても均一化できる仕組みです。
メタ文字の利用例
さらに正規表現を使うと、より複雑なパターンにも対応できます。
例えば、数字と英字が混ざった文字列を、すべてハイフンで区切ってしまいたい、という場合を考えてみましょう。
const mixData = "abc123xyz45"; const replacedMix = mixData.replaceAll(/[0-9]+/g, "-"); console.log(replacedMix); // 出力: "abc-xyz-"
このように、正規表現のメタ文字を組み合わせることで、単純な部分一致だけでなく、数字や特定の文字列パターンに合致する部分を包括的に処理できます。
ただし、正規表現を誤って設定すると想定外のところまで置換されることもあるので、必ずテストを行うようにしましょう。
実務シーンでの活用例
ここでは、日常のプログラミングや業務でよくあるケースをいくつかピックアップして解説します。
単なる文法の知識だけではなく、どうやって実務に応用するのかイメージしやすくなるでしょう。
たとえば、フォームで入力されたテキストに含まれる特定の文字を一気に修正したり、ログに含まれる機密情報を伏せ字にしたりといったシチュエーションが考えられます。
replaceAll
を使うことで、これらを少ないコード量で実装しやすくなるのが利点です。
ユーザー入力のサニタイズ
ユーザーが入力フォームに何か文字列を入れたとき、不要な記号やHTMLタグを取り除きたい場合があります。
もし、あらゆる<script>
タグを空文字に置換したいのであれば、replaceAll
が役立ちます。
function sanitizeInput(input) { return input.replaceAll("<script>", "").replaceAll("</script>", ""); } // 例: "<script>alert('XSS');</script>hello" console.log(sanitizeInput("<script>alert('XSS');</script>hello")); // 出力: "alert('XSS');hello"
もちろん、実際のセキュリティ対策は多面的に行う必要がありますが、このような文字列置換が1つの手段になるのは確かです。
複数箇所にタグが含まれていても、一度に取り除ける点が便利です。
改行文字の一括変換
環境によって改行文字が\r\n
なのか\n
なのか混在しているケースもあります。
アプリケーション内で統一したいときに、すべての\r\n
を\n
にそろえる処理をするとわかりやすいです。
function normalizeNewline(str) { return str.replaceAll("\r\n", "\n"); } const sample = "Line1\r\nLine2\r\nLine3"; console.log(normalizeNewline(sample)); // 出力: // Line1 // Line2 // Line3
このように特定のテキストパターンをまとめて変換する処理は、業務でも比較的よく使われるパターンでしょう。
replaceAll
があることで、誤って1つだけ置換し忘れた、というリスクを減らせます。
ログやデータの変換
サーバーなどで出力されるログファイルを分析や監査のために扱うとき、特定の単語を置き換えて読みやすくしたい場合があります。
たとえば機密情報を伏せ字にするなどの用途です。
ログの中に含まれるメールアドレスをマスクしたいといったときに、ある程度パターン化した正規表現を用いて、replaceAll
で一括置換するのも有効です。
ただし、ログに含まれるすべてのメールアドレスが同じフォーマットとは限らないので、実務では複数パターンを組み合わせることもあります。
JSONテキストの整形
APIから受け取ったJSONデータに余計なエスケープ文字や改行が混在しているケースでは、replaceAll
を使って整形することがあります。
たとえば、クライアントで扱う前に\"
を"
に戻すなどの処理です。
const rawJson = "{\"key\":\"value\",\"anotherKey\":\"test\"}"; const cleanedJson = rawJson.replaceAll("\\\"", "\""); console.log(cleanedJson); // 出力: {"key":"value","anotherKey":"test"}
もちろん、パースに失敗しないようにするために、あらかじめ文字列の状態を確認しておくことも大切です。
ただ、こうした細かい整形が必要なときに、まとめて変換できるreplaceAll
は便利でしょう。
HTMLテンプレートへの埋め込み
テンプレート文字列を作りたいとき、ダミーのプレースホルダーを実際の値に置き換えるパターンがよくあります。
このとき、プレースホルダーが同じものなら、すべて一気に置換してしまうほうがミスを減らせます。
たとえば、{{username}}
などのタグをユーザー名に差し替える場合、複数箇所に現れる{{username}}
をreplaceAll
で一度に処理してしまえばよいわけです。
同じプレースホルダーが繰り返し使われているような状況に特に向いています。
パフォーマンスを意識した使い方
replaceAll
は、1度の呼び出しですべての置換を実行してくれるため、複数の文字列操作を連続して行うよりもコードがわかりやすくまとまるメリットがあります。
ただし、非常に大きな文字列を扱う場合は、メモリ使用量や実行時間にも注意を払っておきたいところです。
文字列の置換は、根本的に新しい文字列を作る処理なので、極端に大きなデータや複雑なパターンを扱うときは、それなりに計算コストがかかります。
実務で大量データを処理する場合は、読み込み方や分割処理なども含めて検討してみてください。
大きな文字列を扱うときの注意点
仮に数十MB以上の文字列を一度に読み込んでreplaceAll
するとなると、メモリ使用量が増加し、処理速度も遅くなる可能性があります。
サーバーサイドのアプリケーションであれば、負荷や応答時間にも影響するでしょう。
こうした状況を回避するには、一度に巨大なテキストを扱わず、小さめのチャンク(かたまり)に分割してから置換する方法も考えられます。
たとえば、ストリームを使って順次読み込みつつ、区切りごとにreplaceAll
をかけていくというやり方もあります。
連鎖的な置換が必要なケース
一度置換した結果、新たに生まれたテキストに対してさらに別の置換が必要になるケースもあります。
複数のreplaceAll
を連続で呼ぶこと自体は問題ありませんが、どの順序で実行するのかは意識しておかないと、重複変換が起きるかもしれません。
たとえば最初に"A"
を"B"
に変え、そのあとに"B"
を別の文字に置き換える処理をすると、最初の置換で変化した部分も再度置換されてしまいます。
このように想定外の置換を防ぐには、対象の文字列やパターンをしっかりと管理し、順序にも注意して実装することが重要です。
変数のスコープと置換範囲
JavaScriptのコードを書く際、グローバルスコープで宣言した変数を気づかないうちに書き換えてしまうケースがあります。
しかし、replaceAll
自体は基本的に新しい文字列を返す処理であり、元の文字列を破壊的に変更しません。
このため、たとえば途中でreplaceAll
を使って編集済みの文字列を別の変数に入れ忘れると、置換結果が反映されない状態になることがあります。
コピペ作業で流れが途切れがちなときは、変数をどこで上書きしているのか意識しましょう。
思わぬ文字列の重複
複数の置換パターンが重複して定義されている場合、どれか一方のreplaceAll
だけで足りる場面もあるかもしれません。
もし重複した処理を何度も呼ぶと、予期しない結果になるだけでなく、パフォーマンスにも影響する可能性があります。
プロジェクトが大規模になるほど、多人数でメソッドを追加・変更していくため、どこでどんな置換が行われているか把握しきれないケースが出てきます。
この点については、コードレビューやテスト体制を整え、どのタイミングでどんな文字列操作を行っているか共有すると良いでしょう。
文字コードとエンコーディング
文字列操作では、文字コードやエンコーディングの違いによって想定外の結果になることも考えられます。
日本語を含む多言語の文字列は、内部的にバイト数が異なることもあるため、replaceAll
がマッチしない場合があるかもしれません。
たとえば、全角スペースと半角スペースを間違えていると、単純な" "
での検索では置換対象にマッチしません。
このような細かい違いを意識しながらコードを書くと、想定外の動作を防ぐ助けになるでしょう。
全角半角の一括変換
全角文字と半角文字が入り混じったデータを統一したいときにも、replaceAll
が役立ちます。
単純に正規表現を組み合わせて、全角を半角に変えるか、あるいはその逆を行うことで、テキストデータを整理しやすくなるでしょう。
ただし、全角英数字を半角英数字に変換するとなると、一部の記号は対応が複雑になることがあります。
このような変換ルールが多岐にわたる場合は、事前にルールを一覧化しておき、一括でreplaceAll
を実行する方針を立てるとスムーズです。
replaceAllをサポートしない環境への対策
最近の多くのJavaScript実行環境でreplaceAll
は利用できますが、何らかの理由でreplaceAll
が使えない場合や、まだこのメソッドが存在しない実行環境を想定しなければならないこともあるかもしれません。
そのようなときは、replace
と正規表現の組み合わせや、代替関数を利用して同等の処理をカバーできます。
本番運用されるコードでは、なるべく特定の環境に依存しすぎない実装が好ましいでしょう。
チーム内でサポートするエンジンやブラウザの要件を確認したうえで、必要ならポリフィルや代替ロジックを用意しておくことが安心です。
ポリフィルの活用
ポリフィルというのは、特定のメソッドがネイティブに存在しない場合に、同等の機能を後から実装するためのコードです。
replaceAll
に対応していない実行環境でも、次のようにポリフィルを定義しておくことで、同じ名前で呼び出せるようにする手段があります。
if (!String.prototype.replaceAll) { // 簡易的なポリフィルの一例 String.prototype.replaceAll = function (search, replacement) { const target = this; const pattern = typeof search === "string" ? new RegExp(search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), "g") : search; return target.replace(pattern, replacement); }; }
上記のコードは簡易的な例ですが、環境に合わせて必要な処理を追加していけば、replaceAll
がない場所でもある程度同じような動きを再現できます。
このように、プロジェクト全体で統一的な方法をとることで、追加開発やメンテナンスをしやすくすることが可能です。
ライブラリの一例
もし大規模な文字列操作を頻繁に行うのであれば、replaceAll
に限らず、各種のユーティリティ関数をまとめたライブラリの利用を検討するケースもあるでしょう。
ただし、小規模な置換がちょっと必要なだけなら、あえて大きなライブラリを導入するより、ネイティブのreplaceAll
を使うほうがシンプルで済みます。
開発の規模やチーム構成によってベストな選択肢は変わりますが、初心者の方が最初から多くの外部ライブラリに依存すると、かえって動作理解が難しくなる恐れもあります。
まずはネイティブのreplaceAll
で十分かどうか検討し、必要に応じてポリフィルを用意するくらいがバランスがいいと考えられます。
実装時に考慮すべき注意点
replaceAll
はとても便利ですが、すべての置換を一度に行うゆえに、想定外の箇所まで置換してしまうリスクも含んでいます。
特に、入力データやファイルの形式が曖昧なときは、どこをどう置換するべきかを明確にしてから実装に入るのが重要です。
また、正規表現を扱う場合には、グローバルフラグを付け忘れたり、エスケープキャラクターを正しく定義しなかったりするとエラーになることもあるため、十分に注意してください。
テストコードを用意して、予期しない部分が置換されていないかのチェックを挟むと安心できます。
思わぬ文字列の重複
たとえば同じ処理を複数回呼び出してしまったり、別の箇所で同じreplaceAll
ロジックを部分的に使っていたりすると、結果的に文字列が想定しない形に変わってしまう可能性があります。
特に複雑な正規表現を扱う場合は、どのパターンとマッチするのかがコード上でやや分かりにくくなることもあるでしょう。
このような問題を回避するには、テストの段階でさまざまな入力パターンを試し、どのように置換されるか確認することが有効です。
小さなケースだけでなく、大きな文字列や特殊文字を含むケースなどもチェックしてみてください。
文字コードとエンコーディング
Unicodeの結合文字やサロゲートペアを扱うようなケースでは、replaceAll
が狙った文字にマッチしないことが起こり得ます。
これらは目視では同じ文字のように見えても、内部的には異なるコードポイントで構成されている場合があるためです。
もし国際化対応や多言語文字列の処理が多いプロジェクトであれば、こうした文字コードの知識もあわせ持っておくと後々トラブルを回避しやすくなります。
replaceAll
に限らず文字列操作全般で注意すべきポイントですが、頭の片隅に置いておきましょう。
予期せぬエスケープシーケンス
正規表現で特殊なメタ文字を扱う場合や、バックスラッシュ"\\"
が頻出する文字列を変換する場合、思わぬ挙動に悩まされることがあります。
例えば、\n
という文字列を文字通り置換したいのに、改行文字として解釈されてしまうなどのケースです。
こうしたトラブルを防ぐためには、バックスラッシュを重ねてエスケープするなどのルールをしっかり把握し、replaceAll
を呼び出す際に正しく記述しましょう。
プロジェクト内で約束事を定めておくと、チームメンバー間の混乱も減らしやすくなります。
思わぬ置換ミスを避けるためには、テスト時に特殊文字を含むパターンも必ずチェックしておくのがおすすめです。
まとめ
ここまで、JavaScriptのreplaceAllメソッドの基本や使い方、実務での活用事例、そして気をつけるべきポイントについて見てきました。
同じ文字列やパターンを何度も置換するとき、コードがすっきり書けてミスも減らせるのがreplaceAllの大きな魅力です。
ただし、あまりにも複雑な文字列パターンや巨大なデータを扱う場合は、処理速度や文字コードの違いにも気を配る必要があります。
適切な正規表現の書き方、実行環境でのサポート状況、そしてテストによる検証を欠かさず行い、安全かつ効率の良い開発をめざしてください。