JavaScriptのreplaceの引数としてfunctionを使用する
JavaScriptのreplaceの第2引数には関数(function)を使用することが出来ます。
その簡単な使い方と簡単な説明です。
※ずっと前にも一度書いたことがあったのですが、読み返したときに意味不明状態になるような内容だったので、情報を整理して改めて書いています。
以前のエントリ:JavaScriptのreplaceの関数オブジェクトを渡せることを知った
一般的なreplaceの使い方
一般的なreplaceの使い方は、
になります。
一般的なreplaceのサンプルコード
var str = 'hoji1hoji2hoji3'; var str2 = str.replace(/(ho)ji([0-9])/g, '$1ge$2'); alert(str2); /* => hoge1hoge2hoge3 */
第2引数にfunctionを渡した場合のreplaceの使い方
第2引数としてfunctionを渡す場合のreplaceの使い方は、
- 第1引数 : 置換え前の文字列(正規表現も可) ※通常の場合と同じ
- 第2引数 : 無名関数 or 関数
になります。
上記の「通常のreplaceの使い方」のサンプルコードと同じ事を、第2引数にfunctionを渡して実現しようとするとこんな感じになります。
※便宜上、console.logやalertを含めています。
第2引数にfunctionを渡した場合のreplaceのサンプルコード
var str = 'hoji1hoji2hoji3'; var str2 = str.replace(/(ho)ji([0-9])/g, function(all, group1, group2){ console.log(arguments); alert(all); /* => hoji1, hoji2, hoji3 */ alert(group1); /* => ho, ho, ho */ alert(group2); /* => 1, 2, 3 */ return group1 + 'ge' + group2; }); alert(str2); /* => hoge1hoge2hoge3 */
ここで重要なのが、第2引数として渡したfunctionの引数に何がわたってくるか?です。
第2引数のfunctionのargumentsの中身
上記のサンプルコードの第2引数のfunctionのargumentsを「console.log」等で出力してみると、こんな感じに表示されます。
※「console.log」ってPHPの「var_dump」みたいで便利です!
FireBugで確認(抜粋)
["hoji1", "ho", "1", 0, "hoji1hoji2hoji3"] ["hoji2", "ho", "2", 5, "hoji1hoji2hoji3"] ["hoji3", "ho", "3", 10, "hoji1hoji2hoji3"]
GoogleChromeで確認(抜粋)
Object 0: "hoji1" 1: "ho" 2: "1" 3: 0 4: "hoji1hoji2hoji3" Object 0: "hoji2" 1: "ho" 2: "2" 3: 5 4: "hoji1hoji2hoji3" Object 0: "hoji3" 1: "ho" 2: "3" 3: 10 4: "hoji1hoji2hoji3"
第2引数にfunctionのargumentsの説明(Webtech Walkerより)
argumentsの中身の説明については、Webtech Walkerさんのページに詳しい説明がありますので、引用させていただきます。
arguments[0] => マッチした文字列全体
arguments[1] ~ arguments[arguments.length - 3] => ()でグルーピングした文字列が順番に
arguments[arguments.length - 2] => マッチした文字が先頭から何文字目か
arguments[arguments.length - 1] => 検索対象の全体の文字列
http://webtech-walker.com/archive/2010/02/15094126.html
少し応用してみる
基本的な使い方が分かったので少し応用してみます。
文字列(%s)にしか対応していないsprintfっぽい関数を作ってみました。
sprintfっぽい関数(arguments版)
この関数の使い方はこんな感じです。
- 第1引数 : フォーマット用文字列(%sのみ対応)
- 第2引数以降 : %sに埋め込む文字列
JavaScriptの関数の引数は「arguments」で配列として参照することができるので、第2引数以降の受け取りにはこれを利用しています。
この関数の場合、第1引数はフォーマット用文字列なので、第2引数以降については「arguments」の2番目以降、つまり「arguments[1]」から参照するようにしています。
var sprintf = function(format){ var ary = arguments; var idx = 1; return format.replace(/%s/g, function(all, group){ return ary[idx++]; }); } var str = sprintf('%s年%s月%s日', '2010','9','16' ); alert(str); /* => 2010年9月16日 */
sprintfっぽい関数(ハッシュ版)
上記の関数の改良版です。この関数の使い方は、
- 第1引数 : フォーマット用文字列(%name%で指定)
- 第2引数 : フォーマットに埋め込む文字列(ハッシュ配列)
上記のarguments版だと、第2引数以降の順番を気にする必要があったので、フォーマット用文字列に「%ハッシュのキー%」という形で、順番に関係なく指定されたキーの値がフォーマットに埋め込まれるようにしてみました。
var sprintf = function(format, hash){ return format.replace(/%([a-z][a-z0-9]+)%/g, function(all, group){ return hash[group]; }); } var str = sprintf('%year%年%month%月%day%日', { 'year':'2010', 'month':'9','day':'16' } ); alert(str); /* => 2010年9月16日 */
やっぱりJavaScriptっておもしろいですわ。
今回参考にしたページ
javascriptのreplaceにfunctionを渡す - Webtech Walker
http://webtech-walker.com/archive/2010/02/15094126.html
#2 プログラマーの三大美徳その2「短気」- 404 Title Not Found:ITpro
http://itpro.nikkeibp.co.jp/article/Watcher/20061005/250058/?ST=oss