若手IT勉強会で「Secrets of the JavaScript Ninja」を読んできた(そして String#replace の凄さを知った!)
今回は7章の Regular expressions について
まず初めに
以下の若手IT勉強会では、jQueryの作者が贈るNinja本こと「Secrets of the JavaScript Ninja」を翻訳しつつ、読んできます。
次回の第22回の詳細は以下のページです。
参加申し込みはこっち
翻訳と言っても、事前になんとなく日本語約をする担当を決めて、当時はその人の翻訳した文章を頼りにするので、英語がわけわかんなくてもある程度はなんとかなると思います。
あ、ちなみに、下記から買えます。まだ本自体書き上がっていないので、適宜アップデートのお知らせがくるはずです(まだ一回しか来てないけど)。
閑話休題
正規表現についての話
ざっくり書くとこんな感じ
- /hogehoge/ だと毎回正規表現オブジェクトがコンパイルされる(ブラウザによってはキャッシュしてくれるかもしれないけど、あてにしない方が良い)
- そんな時は new RegExp でオブジェクトをキャッシュした方が良いよ
- でも、execした後の参照のlastIndexが進んでしまう事には気をつけてね
という話とか、パフォーマンスに関して空白を取り除く(いわゆる trim メソッド)をどのように実装すると効率が良いかについて書いてあった。
そして本題
その他に、 replace メソッドについても詳しく書いてあった。レッシグ曰く「良く使う機能だよねHAHAHA」ということらしいのですが、私は初めて知りました。。。
例えば、replaceで単純な置換をする場合はこんな感じに書くかなと思うのですが
"hogehoge".replace(/^hoge/, "fuga") // => "fugahoge"
で、そうじゃないんだ、マッチさせた '^hoge' に対してちょっとアレンジを加えたいんだよ、という場合も往々にしてあると思います。
上記の例で言うと、例えば '^hoge' の部分だけ強調させたい、とか。
そういう場合、2つの手段があります。どちらにも言えることですが、グルーピングと後方参照を使います。
第二引数に後方参照を使う
後方参照をそのまま使う場合。
replace関数の中でそのまま後方参照使えたんですね。知らなかったです。。。
"hogehoge".replace(/^(hoge)/, "[$1]") // => "[hoge]hoge"
こんな感じでいわゆる後方参照がそのまま使用できます。ただし、その$1に対してメソッドを使う*1のような事はできないみたい*2なので、あまり凝ったことはできなそう。
第二引数にfunctionを使う
第二引数に function を渡すと、$0, $1... に該当する文字列が function の引数として受け取れます。
"hogehoge".replace(/^(hoge)/, function(all, hoge){ return "[" + hoge.toUpperCase() + "]" } ) // => "[HOGE]hoge"
本書では
さらに発展させて replace メソッドの第二引数をうまく使ってURLにくっつくクエリストリングの圧縮とかをやっていた。
なんか知ってればスッゲー当たり前な感じがするけれど
個人的には「なんでこういう機能ないんだろうなー」と思っていたところだったので「そりゃあありますよねー」というメモとしてきちんと書いておくよ。
レッシグさんの含蓄はとても為になりますので、みなさんもぜひ参加すると良いですよ!