いしなお!
2009|03|
2005-03-29 [長年日記]
_ [JavaScript][正規表現] JavaScriptでpreg_replace_callback (17:16)
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に含まされると誤動作するけど、大して危険性もないだろうということで放置。
正解は
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を受け取っちゃうんで、微妙に惜しい結果になった。
_ [Wiki][PHP] WikiParserをアップデート (18:19)
主な変更点としては、
- プラグインとして、従来の関数型プラグインに加え、プラグインクラスに対応。
- プラグインクラスでは、同一プラグイン内でのデータの保持、イベントコールバックによるパーサーからの呼び出し、に対応。要は、footnote(注釈)プラグインみたいなことができるようにした
- パースしている元テキストへのアクセス手段を用意。それに伴いフィルタに対応。フィルタ(プラグインのイベントコールバックの実装と同様)を利用することで、パース処理実行時の元テキストへの加工処理が可能になる。要は、tdview.phpとtdiary_categoryプラグインみたいに、カテゴリ記法に対して前処理でリンクを張ったりできるようにした。
- いくつかのバグをフィックス。
一応現状の基本仕様でフィックスさせつつ、細かいメソッド名とかをもうちょいいじる予定。プラグイン連携のためのメソッドもいくつか追加するかも。
[]
同じようなことで悩んだことがあるのですが、<br>置換後の文字列に関数を指定することができるようです。<br>指定した関数には、$1,$2,$3・・・が渡されます。<br>さっき知りました。これでいけます。<br><br>test = "sdga123lkjdgas1234fasdfas";<br>result = test.replace(/123/g,function(a){return a-0+100});<br>alert(result);
うわ、そんなやり方が! というか、<br>result = test.replace(/123/g, callback($1));<br>なんて書き方は試してみたんだけど、実は、<br>result = test.replace(/123/g, callback)<br>の方が正解だったんですね。<br>まさか暗黙のうちに$1、……がパラメータとして渡されるとは。<br>どうもありがとうございました。