String.prototype.replace() と replaceAll()

replace() は文字列を渡すと最初の1つしか置き換えません。全部置き換える書き方、 $ が特別扱いされる落とし穴、関数で置き換える方法までを実行して確かめます。

実行して検証済み処理系Node 22.22.3対応ES1難易度●●○○○目安8更新

replace() に文字列を渡すと、最初に見つかった1つだけが置き換わります。 全部置き換えたいなら replaceAll() です。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
a+b-c a+b+c a-b-c
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
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
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
$&$&$&

$ が特別扱いされる

置き換える側の文字列に $ があると、そのまま入りません。 $& は「一致した部分」という意味を持ちます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
100$
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
a[1桁]b[2桁]c[3桁]
書き方 入るもの
$$ $ 1文字
$& 一致した部分
$` 一致した部分より前
$' 一致した部分より後ろ
$1 $2 キャプチャした部分

利用者が入力した文字を置き換える側に渡すときは、これが事故になります。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
2026年09月07日
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
2026年9月7日

入れたはずの文字と違うものが出ました。

直しかた

関数を渡します。 関数の戻り値はそのまま入ります

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
2026年09月07日
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
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
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
a\.c abc axc ■

$$$$ が $$ 2つぶんで、結果として $ 1文字になります。読みにくいので、関数を渡すほうを勧めます。

関数で置き換える

関数には一致した文字列が渡ります。位置ごとに違う結果を返せます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
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
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true true

0907 のまま出ています。関数の中で好きに直せるのが、文字列で書く場合との違いです。

文字列で書くなら $1 $2 を使います。こちらのほうが短く読めます。

名前付きキャプチャ

数字より、名前のほうが読めます。

正規表現の特殊文字に気をつける

利用者の入力を第1引数に渡すときも注意が要ります。 replaceAll() に文字列を渡すぶんには安全ですが、正規表現にすると意味が変わります。

.任意の1文字として扱われ、abcaxc も消えました。

文字列で済むなら replaceAll() に文字列を渡してください。 正規表現にする必要があるなら、先に逃がします。

大文字と小文字を無視する

i フラグを付けます。文字列を渡す方法ではできません

g フラグ付きの正規表現を使い回さない

g を付けた正規表現は内部に位置を覚えますreplace() は使うたびに戻しますが、test()exec()戻しません

同じ文字列を調べたのに、2回目は falseです。 1回目で位置が進み、2回目は最後まで行って 0 に戻ったところです。

判定に使うなら g を外すか、毎回作り直してください。

分割の話は String.prototype.split() にまとめてあります。

置き換えではなく「探すだけ」「分けるだけ」で足りる場面も多くあります。判断の目安はこちらです。 → 文字列を探す・分ける・置き換える

この記事の根拠

  1. String.prototype.replace — ECMAScript® 2026 Language Specificationtc39.es
  2. String.prototype.replaceAll — ECMAScript® 2026 Language Specificationtc39.es
  3. String.prototype.replace() — MDNdeveloper.mozilla.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)