replace() は文字列を渡すと最初の1つしか置き換えません。全部置き換える書き方、 $ が特別扱いされる落とし穴、関数で置き換える方法までを実行して確かめます。
replace() に文字列を渡すと、最初に見つかった1つだけが置き換わります。
全部置き換えたいなら replaceAll() です。
example.js
const text = 'a-b-c';
console.log(text.replace('-', '+'));
console.log(text.replaceAll('-', '+'));
console.log(text);
出力書き換えて実行できます
a+b-c
a+b+c
a-b-c
example.js
const text = 'a-b-c';
console.log(text.replace(/-/, '+'));
console.log(text.replace(/-/g, '+'));
console.log(text.replaceAll(/-/g, '+'));
出力書き換えて実行できます
a+b-c
a+b+c
a+b+c
元の文字列は変わりません。戻り値を受け取ってください。
上のコードは書き換えて実行できます。'-' を 'b' にしてみてください。
何を渡せるか
| 第1引数 |
置き換わる数 |
文字列(replace) |
最初の1つだけ |
文字列(replaceAll) |
全部 |
正規表現(g なし) |
最初の1つだけ |
正規表現(g あり) |
全部 |
javascript
console.log('a-b'.replaceAll(/-/, '+'));
TypeError: String.prototype.replaceAll called with a non-global RegExp argument
javascript
console.log('価格'.replace('価格', '$&$&'));
console.log('a'.replace('a', '$$'));
console.log('a'.replace('a', '100$'));
価格価格
$
100$
replaceAll() に正規表現を渡すときは g が必須です。
無いと例外になります。
javascript
const userInput = "$&$&$&";
console.log('ここ'.replace('ここ', userInput));
ここここここ
example.js
const userInput = "$&$&$&";
console.log('ここ'.replace('ここ', () => userInput));
出力書き換えて実行できます
$&$&$&
$ が特別扱いされる
置き換える側の文字列に $ があると、そのまま入りません。
$& は「一致した部分」という意味を持ちます。
example.js
const userInput = "100$";
console.log('X'.replace('X', userInput.replaceAll('$', '$$$$')));
出力書き換えて実行できます
100$
example.js
const text = 'a1b22c333';
console.log(text.replace(/\d+/g, (m) => `[${m.length}桁]`));
出力書き換えて実行できます
a[1桁]b[2桁]c[3桁]
| 書き方 |
入るもの |
$$ |
$ 1文字 |
$& |
一致した部分 |
$` |
一致した部分より前 |
$' |
一致した部分より後ろ |
$1 $2 … |
キャプチャした部分 |
利用者が入力した文字を置き換える側に渡すときは、これが事故になります。
example.js
const text = '2026-09-07';
console.log(text.replace(/(\d{4})-(\d{2})-(\d{2})/, (m, y, mo, d) => `${y}年${mo}月${d}日`));
出力書き換えて実行できます
2026年09月07日
example.js
const text = '2026-09-07';
console.log(text.replace(/(\d{4})-(\d{2})-(\d{2})/, (m, y, mo, d) => `${y}年${Number(mo)}月${Number(d)}日`));
出力書き換えて実行できます
2026年9月7日
入れたはずの文字と違うものが出ました。
直しかた
関数を渡します。 関数の戻り値はそのまま入ります。
example.js
console.log('2026-09-07'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$1年$2月$3日'));
出力書き換えて実行できます
2026年09月07日
example.js
const text = '2026-09-07';
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
console.log(text.replace(re, '$<year>/$<month>/$<day>'));
console.log(text.match(re).groups.year);
出力書き換えて実行できます
2026/09/07
2026
$ を自分で書ける形にしたいなら、$$ に置き換えてから渡します。
javascript
const keyword = 'a.c';
console.log('abc axc a.c'.replaceAll(keyword, '■'));
console.log('abc axc a.c'.replace(new RegExp(keyword, 'g'), '■'));
abc axc ■
■ ■ ■
example.js
function escapeRe(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
const keyword = 'a.c';
console.log(escapeRe(keyword));
console.log('abc axc a.c'.replace(new RegExp(escapeRe(keyword), 'g'), '■'));
出力書き換えて実行できます
a\.c
abc axc ■
$$$$ が $$ 2つぶんで、結果として $ 1文字になります。読みにくいので、関数を渡すほうを勧めます。
関数で置き換える
関数には一致した文字列が渡ります。位置ごとに違う結果を返せます。
example.js
const text = 'Apple apple APPLE';
console.log(text.replaceAll('apple', '■'));
console.log(text.replace(/apple/gi, '■'));
出力書き換えて実行できます
Apple ■ APPLE
■ ■ ■
javascript
const re = /a/g;
console.log(re.test('abc'));
console.log(re.test('abc'));
console.log(re.lastIndex);
true
false
0
キャプチャした部分は2つ目以降の引数で受け取ります。
example.js
console.log(/a/.test('abc'));
console.log(/a/.test('abc'));
出力書き換えて実行できます
true
true
09 と 07 のまま出ています。関数の中で好きに直せるのが、文字列で書く場合との違いです。
文字列で書くなら $1 $2 を使います。こちらのほうが短く読めます。
名前付きキャプチャ
数字より、名前のほうが読めます。
正規表現の特殊文字に気をつける
利用者の入力を第1引数に渡すときも注意が要ります。
replaceAll() に文字列を渡すぶんには安全ですが、正規表現にすると意味が変わります。
. が任意の1文字として扱われ、abc も axc も消えました。
文字列で済むなら replaceAll() に文字列を渡してください。
正規表現にする必要があるなら、先に逃がします。
大文字と小文字を無視する
i フラグを付けます。文字列を渡す方法ではできません。
g フラグ付きの正規表現を使い回さない
g を付けた正規表現は内部に位置を覚えます。
replace() は使うたびに戻しますが、test() や exec() は戻しません。
同じ文字列を調べたのに、2回目は falseです。
1回目で位置が進み、2回目は最後まで行って 0 に戻ったところです。
判定に使うなら g を外すか、毎回作り直してください。
分割の話は
String.prototype.split() にまとめてあります。
置き換えではなく「探すだけ」「分けるだけ」で足りる場面も多くあります。判断の目安はこちらです。
→ 文字列を探す・分ける・置き換える