JavaScript における文字列置換 (String#replace メソッド)

JavaScript において文字列の置換 (文字列中のある部分文字列を別の文字列に変換する) を行うためには String#replace メソッドを使用します。

// 第 1 引数が置換対象の文字列, 第 2 引数が置換後の文字列
window.alert( "test".replace("t", "a") );
// => "aest" と表示

ここで、最初の "t" は "a" に置換されていますが、2 番目の "t" は置換されていません。 これは、デフォルトでは String#replace メソッドは最初にマッチしたものしか置換しないためです。 該当する文字全てを置換したい場合は、第 3 引数に "g" を渡す方法 (これは ECMAScript の仕様にはない模様. JavaScriptJScript の独自拡張ぽい) や、第 1 引数を g フラグ付きの RegExp オブジェクトにする方法があります。

// 第 3 引数に "g" を渡す方法
window.alert( "test".replace("t", "a", "g") );
// 第 1 引数を RegExp オブジェクトにする方法
window.alert( "test".replace(/t/g, "a") );
// => どちらの方法でも "aesa" と表示

この例ではどちらの方法でも結果は同じですが、前者は 「第 1 引数の文字列と同値のもの」 を置換し、後者は 「第 1 引数の正規表現にマッチするもの」 を置換するという違いがあります。 当然ながら正規表現を使った方が柔軟な置換を行う事ができます。

後方参照

正規表現でマッチした部分や、括弧でくくりグループ化した部分、マッチした部分よりも前全部、または後全部といったものを第 2 引数の文字列の中で指定する事もできます。

正規表現にマッチした部分は "$&"、グループ化した部分は前から順に "$1"、"$2"、"$3" ...、マッチした部分の前全部は "$`"、後全部は "$'" で指定できます。 また、$ 記号を直接出したい場合は "$$" と入力します。

// マッチした部分 (数字) を <...> で囲む
window.alert( "test100and200hogehoge4fuga".replace(/\d+/g, "<$&>") );

関数を利用したより柔軟な置換

さらに、第 2 引数には関数を指定する事もできます。 マッチした文字列や、グループ化した部分の文字列、また置換対象の文字全体などが関数の引数として渡され、関数の戻り値が置換後の文字として使われます。 関数内で条件分岐などをして置換後の文字を柔軟に変化させる事ができます。 第 1 引数としてマッチした文字列が渡されますので、簡単な置換であれば第 1 引数だけ使えば良いでしょう。

例えば、以下のように XML の組み込みエンティティ参照の文字列を実体に変換する事も簡単にできます。 (この例では各エンティティ参照を 1 種類ずつ処理しても大丈夫ですが、文字参照も絡んでくるとこの例のように一度に処理する必要が出てきます。)

// XML の組み込みエンティティ参照の文字列を実体に変換する関数
function unescapeForXML(a) {
    var str = null;
    if ( a == "&amp;" ) { str = "&"; }
    else if ( a == "&gt;" ) { str = ">"; }
    else if ( a == "&lt;" ) { str = "<"; }
    else if ( a == "&quot;" ) { str = '"'; }
    else if ( a == "&apos;" ) { str = "'"; }
    else { str = ""; } // ここは例外を発生させるべきかも
    return str;
}
var str = "teat: 200 &gt; 100 &amp;&amp; 300 &lt; 400";
new_str = str.replace(/&amp;|&gt;|&lt;|&quot;|&apos;/g, unescapeForXML);
window.alert(new_str);
// => "teat: 200 > 100 && 300 < 400" と表示される

参考

下記ページが参考になります。 第 2 引数を関数にしたときに、関数に渡される引数がどうなるかなどは ECMAScript (JavaScriptJScript の統一仕様) の仕様書をご覧ください。