「全置換」って何をするユーティリティ?
まずイメージからいきましょう。
「この文字列の中にある foo を、全部 bar に変えたい」という場面、よくありますよね。
"foo foo foo" → "bar bar bar"
"2024/01/01" の "/" を全部 "-" にしたい → "2024-01-01"
" "(全角スペース)を全部 " "(半角スペース)にしたい
こういう「出てくる全部を置き換える」のが「全置換」です。
逆に、「最初の1個だけ置き換える」のは「単一置換」です。
業務では、ログ整形・CSV 整形・フォーマット変換・マスク処理など、
「同じパターンを全部置き換えたい」場面が本当に多いので、
“全置換ユーティリティ”を一つ持っておくとかなり便利です。
JavaScript 標準の replace と replaceAll の基本
まずは replace の落とし穴
JavaScript には String.prototype.replace があります。
const s = "foo foo foo";
const r = s.replace("foo", "bar");
console.log(r); // "bar foo foo"
JavaScriptここで重要なのは、replace は「最初の1箇所だけ」しか置き換えないということです。
「全部置き換えたい」と思っているのに、1個しか変わらない——これが初心者が最初にハマるポイントです。
replaceAll なら「全部」置き換えられる
最近の JavaScript には replaceAll があります。
const s = "foo foo foo";
const r = s.replaceAll("foo", "bar");
console.log(r); // "bar bar bar"
JavaScriptこれは名前の通り、「一致したところを全部置き換える」メソッドです。
モダンな環境(最近のブラウザ・Node.js)なら、まずこれでOKです。
正規表現+g フラグで「全置換」する方法
replaceAll がない環境でも「全置換」はできる
古い環境や、replaceAll がまだ使えない状況では、
正規表現+g フラグを使って全置換を実現します。
const s = "foo foo foo";
const r = s.replace(/foo/g, "bar");
console.log(r); // "bar bar bar"
JavaScript/foo/g の g は「global(全体)」の意味で、
「文字列全体を対象に、マッチしたところを全部置き換える」という指定です。
ここでの重要ポイント
全置換をしたいときに、replace("foo", "bar") と書いてしまうと「1個だけ」しか変わらない。replaceAll("foo", "bar") か replace(/foo/g, "bar") を使うと「全部」変わる。
この違いを、頭ではなく「手で動かして体で覚える」と強いです。
全置換ユーティリティを自作する
文字列パターン用のシンプルなユーティリティ
まずは「単純な文字列を全部置き換える」ユーティリティから。
function replaceAllString(text, search, replacement) {
if (text == null) return "";
if (search == null || search === "") return String(text); // 空検索はそのまま返す
const s = String(text);
const target = String(search);
const repl = String(replacement);
// 正規表現の特殊文字をエスケープ
const escaped = target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const regex = new RegExp(escaped, "g");
return s.replace(regex, repl);
}
JavaScriptここが少し大事なので、噛み砕きます。
text が null / undefined でも落ちないようにしている。search が空文字のときは、そのまま返す(無限にマッチしてしまうのを防ぐ)。search をそのまま正規表現に入れると、. や * などが「特別な意味」を持ってしまう。
それを防ぐために、[.*+?^${}()|[\]\\] を \ でエスケープしている。new RegExp(escaped, "g") で「全体を対象にした正規表現」を作り、replace で全置換している。
これで、次のように使えます。
replaceAllString("foo foo foo", "foo", "bar"); // "bar bar bar"
replaceAllString("2024/01/01", "/", "-"); // "2024-01-01"
replaceAllString("a.b.c", ".", "-"); // "a-b-c"(. も安全に置換できる)
JavaScript正規表現をそのまま使いたい場合
「数字だけを全部消したい」「連続する空白を1個にしたい」など、
パターンで置き換えたいときは、正規表現をそのまま受け取るユーティリティもありです。
function replaceAllRegex(text, pattern, replacement) {
if (text == null) return "";
if (!(pattern instanceof RegExp)) {
throw new Error("pattern は RegExp である必要があります");
}
const s = String(text);
// g フラグが付いていない場合は付け直す
const flags = pattern.flags.includes("g")
? pattern.flags
: pattern.flags + "g";
const regex = new RegExp(pattern.source, flags);
return s.replace(regex, replacement);
}
JavaScript使い方はこうです。
replaceAllRegex("abc123def456", /\d+/g, ""); // "abcdef"
replaceAllRegex("a b c", /\s+/g, " "); // "a b c"
JavaScript業務での具体的な使いどころ
日付フォーマットの変換
API から "2026/02/19" のような日付文字列が来て、
画面では "2026-02-19" として表示したい、というのはよくあります。
function normalizeDateFormat(dateStr) {
return replaceAllString(dateStr, "/", "-");
}
normalizeDateFormat("2026/02/19"); // "2026-02-19"
JavaScript全角スペース・タブなどの整理
入力値の中に、全角スペースやタブが混ざっていることがあります。
それを全部「半角スペース1個」にそろえたい。
function normalizeSpaces(text) {
if (text == null) return "";
// 全角スペースを半角に
let s = replaceAllString(text, " ", " ");
// 連続する空白を1個に
s = replaceAllRegex(s, /\s+/g, " ");
return s.trim();
}
normalizeSpaces(" 山田 太郎 "); // "山田 太郎"
JavaScriptマスク処理(個人情報の一部を隠す)
例えば、メールアドレスのユーザー名部分を * にしたいとします。
function maskEmail(email) {
if (email == null) return "";
const [user, domain] = String(email).split("@");
if (!domain) return email;
const maskedUser = user.replace(/./g, "*"); // 全文字を * に
return `${maskedUser}@${domain}`;
}
maskEmail("taro@example.com"); // "****@example.com"
JavaScriptここでは replace(/./g, "*") で「全置換」を使っています。
設計として意識してほしいこと
「全置換」と「単一置換」を意識的に使い分ける
一番大事なのは、
「今やりたいのは“最初の1個だけ”なのか、“全部”なのか」を意識することです。
replace は「1個だけ」。replaceAll / 正規表現+g は「全部」。
ここを曖昧にしたまま書き始めると、
「一部だけ変わって残りがそのまま」というバグを生みやすくなります。
「検索パターンのエスケープ」をユーティリティに閉じ込める
replaceAllString の中でやったように、. や * などの正規表現の特殊文字をエスケープする処理は、
毎回自分で書くとほぼ確実にミスります。
なので、
「文字列としての検索パターンを全部置き換えたい」 → replaceAllString
「正規表現としてのパターンを使いたい」 → replaceAllRegex
のように、用途ごとにユーティリティを分けておくと安全です。
ちょっとだけ手を動かしてみる
コンソールで、次のあたりを試してみてください。
"foo foo foo".replace("foo", "bar");
"foo foo foo".replaceAll("foo", "bar");
"2024/01/01".replaceAll("/", "-");
replaceAllString("a.b.c", ".", "-");
replaceAllRegex("a b c", /\s+/g, " ");
JavaScript「どこまでが変わって、どこが変わらないか」を目で確認すると、
「単一置換」と「全置換」の違いがかなりクリアになります。
そのうえで、自分のプロジェクトに
export function replaceAllString(text, search, replacement) { ... }
export function replaceAllRegex(text, pattern, replacement) { ... }
JavaScriptを一つ置いて、
「“全部置き換えたい”ときは必ずここを通す」
というルールにしてみてください。
それができた瞬間、あなたの文字列置換は
「なんとなく replace を呼んでいる状態」から
「意図を持って全置換をコントロールしている状態」に、一段レベルアップします。
