日記
JavaScriptでpreg_replace_callback (17:16)Edit

WikiParserをJavaScriptに移植してみようかと思ったら、preg_replace_callback相当の正規表現(Perlで言うと/eg)が見あたらない。っつーか、ないんだよね?

しょうがないんで、こんな感じで動かしてみたんだけど、なんとも不格好な感じ。もうちょいいい書き方ないかなー。

function replace(str)
{
str = str.replace(/(123)/g, "' + callback('$1') + '");
str = str.replace(/'/g, "\\'");
str = str.replace(/\\' \+ callback\(\\'(.+?)\\'\) \+ \\'/g, "' + callback('$1') + '");
str = eval("'" + str + "'");
return str;
}
function callback(str)
{
str = eval(str) + 100;
return str;
}
test = "sdga123lkjdgas1234fasdfas";
alert(test);
result = replace(test);
alert(result);

ちなみにテンポラリの式をわざと対象のstrに含まされると誤動作するけど、大して危険性もないだろうということで放置。

正解は

malaさんからきれいな解答を教えてもらいました

function replace(str)
{
str = str.replace(/123/g, callback);
return str;
}
function callback(str)
{
str = eval(str) + 100;
return str;
}
test = "sdga123lkjdgas1234fasdfas";
alert(test);
result = replace(test);
alert(result);

これでOK。replaceの第2パラメータに関数を渡すと、その関数のパラメータとして、lastMatch(というかマッチした全体)、$1、$2、……が渡されて呼ばれる模様。で、その関数の戻り値として置換結果文字列を返してやればいい。

str = str.replace(/(123)/g, callback($1));

とか

str = str.replace(/(123)/g, callback(RegExp.$1));

なんて表現は試してみたんだけどなー。

ちなみに後者の表現だと、RegExp.$1はここの/123/gではなく、その前に評価された正規表現の結果の$1を受け取っちゃうんで、微妙に惜しい結果になった。

Published At2005-03-29 00:00Updated At2005-03-29 00:00