String.prototype.replace

こんな利用の仕方もできるのでは?と思いつつ半信半疑だったので、実際に挑戦して出来たのでメモ。String.prototype.replace賢いね。

replaceイロイロ

スタンダードなreplace
var str = "foo foo";
str = str.replace("foo","bar");

// bar foo が表示される。
alert(str);
正規表現を利用したreplace
var str = "foo foo";
str = str.replace(/foo/,"bar");

// bar bar が表示される。
alert(str);
第二引数は実は関数でもいける。
var str = "foo foo";

function f(arg)
{
    f.i++;
    if(arg == 'foo') retrun "bar" + f.i; 
    return "";
}
f.i = 0;

str = str.replace("foo",f);

// bar1 bar2が表示される。
alert(str);
余談です。

第一引数は文字列オブジェクトか正規表現オブジェクトでもいいので…。

function foo(){
    return "foo";
}

var str = "foo foo";
str = str.replace(foo(),"bar");
//bar fooが表示される。 
alert(str);

因みに

第二引数が関数の場合にその関数に渡される引数は3個の引数とのこと(文字列の場合)。正規表現の場合は m + 3個の引数になります(mは正規表現の()で保存された奴)(ECMAScript仕様より)僕の説明だと悪いので実際にサンプル書いておきます。

var str = "foo foo";

function f()
{
   alert(arguments[0]);
   alert(arguments[1]);
   alert(arguments[2]);
   alert(arguments[3]);
}

str.replace('foo',f);
/*
このとき 以下のように出力されます。
  foo // マッチした文字
  0 // マッチしたオフセット
  foo bar // マッチした文字列
  undefined // 当然
*/

str.replace(/(bar)/,f);
/*
  bar // 正規表現で保存された文字
  bar // マッチした文字
  4 // マッチしたオフセット
  foo bar // マッチした文字列  
*/

こんなコードありました。

"$1,$2".replace(/(\$(\d))/g, "$$1-$1$2");

結果は↓
"$1-$11,$1-$22";