「正規表現置換」ができると何が嬉しいのか
まずイメージからいきます。
普通の置換は「この文字列を、この文字列に変える」だけです。
"2026/02/19" の "/" を "-" に変える
"foo foo foo" の "foo" を "bar" に変える
でも業務では、もっと“パターン”で置き換えたいことがたくさんあります。
数字だけを全部消したい。
連続する空白を1個にまとめたい。
電話番号の「数字だけ」を抜き出してフォーマットし直したい。
こういう「形にルールがあるものをまとめて置き換える」ときに使うのが、正規表現置換です。
JavaScript の replace と正規表現の基本
replace は「文字列」も「正規表現」も受け取れる
String.prototype.replace は、第一引数に
文字列だけでなく「正規表現」も渡せます。
const s = "abc123def456";
s.replace("123", "X"); // "abcXdef456"(最初の1箇所だけ)
s.replace(/\d+/g, "X"); // "abcXdefX"(数字のまとまりを全部 X に)
JavaScript/\d+/g が正規表現です。
\d は「数字1文字」+ は「1回以上の繰り返し」g は「global(全体)」=全部対象にするフラグ
つまり「数字が1文字以上続くところを全部」という意味になります。
ここでのポイントは、
文字列 "123" を指定すると「その文字列に完全一致したところだけ」。
正規表現 /\d+/g を指定すると「数字のまとまり全部」。
というふうに、「何を検索対象にするか」をもっと柔軟に書ける、ということです。
正規表現置換ユーティリティの基本形
「パターン」と「置換後」を受け取る関数
まずは、素直なラッパーから作ってみます。
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重要なポイントを噛み砕きます。
text が null / undefined でも落ちないようにしている。
pattern がちゃんと RegExp かどうかをチェックしている。pattern.flags からフラグ(i や g など)を取り出している。g が付いていなければ足して、新しい正規表現を作り直している。
最後は replace に渡しているだけ。
これで、「正規表現でマッチしたところを全部置き換える」関数になります。
具体例で「正規表現置換」の威力を感じる
数字だけを全部消す
replaceAllRegex("abc123def456", /\d+/g, ""); // "abcdef"
JavaScript「数字が1文字以上続くところ」を全部空文字に置き換えています。
ログから ID を消したり、マスクしたりするときに使えます。
連続する空白を1個にまとめる
replaceAllRegex("a b c", /\s+/g, " "); // "a b c"
JavaScript\s は「空白文字(スペース・タブ・改行など)」です。\s+ で「1文字以上の空白」を表し、それを " "(半角スペース1個)に置き換えています。
入力値の整形や、CSV の前処理などでよく使うパターンです。
数字だけを抜き出してフォーマットする(電話番号)
正規表現置換は、「消す」だけでなく「整える」にも使えます。
function normalizePhone(phone) {
if (phone == null) return "";
// 数字以外を全部消す
const digits = String(phone).replace(/\D+/g, "");
// 例: 09012345678 → 090-1234-5678 っぽく整形(ざっくり例)
return digits.replace(/(\d{3})(\d{4})(\d{4})/, "$1-$2-$3");
}
normalizePhone("090-1234-5678"); // "090-1234-5678"
normalizePhone("090 1234 5678"); // "090-1234-5678"
normalizePhone("090-1234-5678(代表)"); // "090-1234-5678"
JavaScriptここでは二段階で正規表現置換を使っています。
\D+ で「数字以外」を全部消す。/(\d{3})(\d{4})(\d{4})/ で「3桁・4桁・4桁」に分けて $1-$2-$3 で再構成する。
この「キャプチャして、置換側で $1 $2 として使う」のが、正規表現置換の強力なところです。
置換側で「マッチした内容」を使うテクニック
キャプチャグループと , , …
さっきの電話番号の例のように、
正規表現の中で () で囲んだ部分は「キャプチャグループ」として、
置換文字列の中で $1, $2, … として参照できます。
"2026-02-19".replace(/(\d{4})-(\d{2})-(\d{2})/, "$1/$2/$3");
// "2026/02/19"
JavaScript(\d{4}) → $1(\d{2}) → $2(\d{2}) → $3
という対応です。
関数を渡して、もっと柔軟に置換する
置換側に「文字列」ではなく「関数」を渡すこともできます。
const text = "price: 1200, tax: 120";
const result = text.replace(/\d+/g, (match) => {
const num = Number(match);
return (num * 2).toString();
});
console.log(result); // "price: 2400, tax: 240"
JavaScriptここでは、
\d+ で数字のまとまりにマッチする。
マッチしたたびにコールバック関数が呼ばれる。match にはマッチした文字列(”1200″ や “120”)が入る。
それを数値に変換して2倍して、文字列に戻して返す。
という流れです。
業務でいうと、
金額を一括で税抜→税込に変換する。
特定のパターンだけマスクする。
ログの中の ID を別の形式に変換する。
といった処理を、かなり柔軟に書けます。
正規表現置換ユーティリティをどう設計するか
「よく使うパターン」を関数に切り出す
正規表現そのものは強力ですが、
毎回 /\s+/g や /\D+/g を生で書いていると、
読みづらいし、コピペミスもしやすくなります。
なので、業務でよく使うものは、
「意味のある名前を付けたユーティリティ」にしてしまうのがおすすめです。
例えば:
export function collapseSpaces(text) {
return replaceAllRegex(text, /\s+/g, " ");
}
export function removeNonDigits(text) {
return replaceAllRegex(text, /\D+/g, "");
}
JavaScript呼び出し側は、
collapseSpaces("a b c"); // "a b c"
removeNonDigits("TEL: 03-1234-5678"); // "0312345678"
JavaScriptのように、「何をしたいか」だけを読めば意味が分かるコードになります。
「生の正規表現」を散らさない
プロジェクトのあちこちに /\s+/g や /\d{4}-\d{2}-\d{2}/ が散らばると、
仕様変更(例えば「日付のフォーマットが変わった」)のときに地獄を見ます。
なので、
正規表現はできるだけユーティリティ関数の中に閉じ込める。
呼び出し側は「意味のある関数名」だけを見る。
という構造にしておくと、
後から見たときの理解コストも、変更コストも一気に下がります。
ちょっとだけ手を動かしてみる
コンソールで、次のあたりを試してみてください。
"abc123def456".replace(/\d+/g, "");
"a b c".replace(/\s+/g, " ");
"2026-02-19".replace(/(\d{4})-(\d{2})-(\d{2})/, "$1/$2/$3");
replaceAllRegex("abc123def456", /\d+/g, "");
replaceAllRegex("a b c", /\s+/g, " ");
JavaScript「どこがマッチして、どう置き換わるか」を目で確認すると、
正規表現置換のイメージがかなりクリアになります。
そのうえで、自分のプロジェクトに
export function replaceAllRegex(text, pattern, replacement) { ... }
export function collapseSpaces(text) { ... }
export function removeNonDigits(text) { ... }
JavaScriptのようなユーティリティを一つ置いて、
「パターンで置き換えたいときは必ずここを通す」
というルールにしてみてください。
それができた瞬間、あなたの文字列処理は
「場当たり的な replace の寄せ集め」から
「意図を持って設計された正規表現置換ユーティリティ」に、一段レベルアップします。
