JavaScriptのString#matchと正規表現
どうもよくわかってなかったというか、誤解していた部分があったようなので、とりあえずFirebugで書いてみた。
var log = console.log; log("a/a".match("a")); // "a" log(RegExp.$1); // log("a/a".match("(a)/")); // "a/", "a" log(RegExp.$1); // a log("b/b".match(/(\w)\//)); // "b/" , "b" log(RegExp.$1); // b log("c/c".match("(\w)")); // null log(RegExp.$1); // b log("d/d".match("(\\w)")); // "d" ,"d" log(RegExp.$1); // d log("e/e/e/".match(new RegExp("(e)/","g"))); // "e/", "e/", "e/" log(RegExp.$1); // d log("e/e".match(new RegExp("(\w)","g"))); // null log(RegExp.$1); // d log("f/ff".match(new RegExp("(\\w)","g"))); // "f", "f", "f" log(RegExp.$1); // f
- String#matchはnew RegExp("expression")や/expression/を使わなくても正規表現が有効
- /expression/以外では、\を\でエスケープする必要がある(\\w)
- /は/expression/で正規表現を書いたときのみエスケープが必要(/\//など)で、そうでなければ必要ない
matchをreplaceに変えてみると、
var log = console.log; log("replace"); log("a/a".replace("a","x")); // x/a log(RegExp.$1); // log("a/a".replace("(a)/","x")); // a/a log(RegExp.$1); // log("b/b".replace(/(\w)\//,"x")); // xb log(RegExp.$1); // b log("c/c".replace("(\w)","x")); // c/c log(RegExp.$1); // b log("d/d".replace("(\\w)","x")); // d/d log(RegExp.$1); // b log("e/e/e/".replace(new RegExp("(e)/","g"),"x")); // xxx log(RegExp.$1); // e log("e/e".replace(new RegExp("(\w)","g"),"x")); // e/e log(RegExp.$1); // e log("f/ff".replace(new RegExp("(\\w)","g"),"x")); // x/xx log(RegExp.$1); // f log("g".replace(new RegExp("(\\w)","g"), RegExp.$1 + "$1x")); // fgx log("h".replace(new RegExp("(\\w)","g"), function(){return RegExp.$1 + "x"} )); // hx
- String#replaceはnew RegExp("expression")や/expression/を使わないと正規表現が有効にならない
- replaceの場合も、RegExp.$nは有効
- replaceの第二引数にRegExp.$1を書くとreplaceの実行前にRegExp.$1が参照されるので、前回の値が(存在すれば)入っていることになる。第二引数をfunctionにして、その中でRegExp.$1を参照するとそのときマッチした値が入っている。(考えてみれば当たり前。functionには引数としてマッチした値が渡ってくるのでRegExp.$nを使う必要は特にない。)
正直String#matchが、デフォで正規表現が有効になっていることに驚きました。
で、oreillyのJavaScript第5版で確認してみると、p.215あたりにちゃんと書いてありました。
String#search、String#matchは正規表現以外の引数を渡されるとRegExpに渡され、String#replaceは文字列を渡すと文字列そのもの使うので、注意してください。と。
知らぬは己ばかりなり。