置換とキャプチャ
このレッスンで分かること
replaceは元の文字列を変えず、書き換えた新しい文字列を返します- 丸かっこで取り出した部分は
$1で差し込め、加工したいときは関数を渡します
探せるようになっても、表示は直せない
ここまでは「当たるか」「当たった文字は何か」を見てきました。学習ログに 2026-04-01 と書いた日付を見つけられるようにはなりましたが、画面に出したい 2026年4月1日 にはなりません。書き換えるには replace を使います。
JavaScript
const text = "作品は5件です";
console.log(text.replace("件", "作品")); // 作品は5作品です
console.log(text); // 作品は5件です 元は変わらないreplace は元の文字列を変えません。新しい文字列を返すだけです。戻り値を受け取り忘れると、何も起きていないように見えます。
第 1 引数に正規表現を渡すと、形で探して書き換えられます。ただし g を付けないと最初の 1 件しか置き換わりません。
JavaScript
const log = "AB12 と CD34";
console.log(log.replace(/[A-Z]{2}\d{2}/, "[コード]")); // [コード] と CD34
console.log(log.replace(/[A-Z]{2}\d{2}/g, "[コード]")); // [コード] と [コード]replaceAll を使えば g を書かずに全部を置き換えられます。ただし正規表現を渡すときは g が必須で、無いと TypeError で落ちます。
丸かっこで取り出して $1 で差し込む
正規表現の中の丸かっこをキャプチャグループと呼びます。囲んだ部分は番号付きで取り出せて、置換文字列の中では $1 $2 の形で参照します。番号は左の丸かっこから数えて 1 始まりです。
JavaScript
console.log("0312345678".replace(/(\d{2})(\d{4})(\d{4})/, "$1-$2-$3"));
// 03-1234-5678
console.log("山田 太郎".replace(/(\S+)\s+(\S+)/, "$2 $1"));
// 太郎 山田当たった全体は $& で参照できます。ドル記号そのものを出したいときは $$ と書きます。
$1が使えるのは置換文字列の中だけです。テンプレートリテラルの${...}とは別物なので、バッククォートで囲んでも$1は$1のまま扱われます。
$1 では加工ができない
$1 は、取り出した文字をそのまま差し込むだけです。"04" を 4 にするような加工はできません。加工したいときは、第 2 引数に文字列ではなく関数を渡します。当たるたびに呼ばれ、その戻り値が置き換え後の文字列になります。
引数の並びは決まっていて、第 1 引数が当たった全体、第 2 引数からがキャプチャグループの左からの順です。
JavaScript
console.log("html css js".replace(/\w+/g, (match) => match.toUpperCase()));
// HTML CSS JS当たった文字を見てから何を返すか決められるので、表を引く形にすると分岐を書かずに済みます。
JavaScript
const escapeMap = { "&": "&", "<": "<", ">": ">" };
console.log("5 < 10 & 20".replace(/[&<>]/g, (ch) => escapeMap[ch]));
// 5 < 10 & 20入門で innerHTML に文字を流し込むと、入力に含まれた < がタグとして解釈されてしまう話が出ました。上のような関数を通しておけば、文字として表示されます。先頭の 0 を落とすような数値の加工も、Number に通すだけで済みます。Number("04") は 4 です。文字列の置換では書けなかったことが、関数の中ならふつうの JavaScript として書けます。
置換関数の中で
returnを書き忘れると、戻り値がundefinedになり、当たった箇所が文字列の"undefined"に置き換わります。エラーにならないので、画面にundefinedが並んで初めて気づきます。
よくある間違い
- 戻り値を受け取らない —
text.replace(...)を呼びっぱなしにしてtextを返すと、何も変わっていない文字列が返ります。replaceは元を書き換えないので、必ず戻り値のほうを使います - 置換関数の第 1 引数をキャプチャだと思う — 第 1 引数は当たった全体で、キャプチャは第 2 引数からです。1 つずらすと、1 番目のつもりで当たった全体を受け取ります
要件
- 関数名は formatLogDates、引数は文字列の text を 1 つ受け取る
- 4 桁の数字とハイフンで区切られた 2 桁の数字 2 つ、という形をすべて置き換える
- 月と日の先頭の 0 は落とす。04 は 4、01 は 1 にする
- 戻り値は置き換え後の文字列。日付が無ければ元の文字列をそのまま返す