JavaScript の正規表現マッチング
JavaScript で正規表現 (RegExp オブジェクト) を使ってマッチングする方法。 しょっちゅう忘れてしまううえに ECMAScript 仕様に適合した方法があまり web 上に書かれていないようなので軽くメモしておきます。
RegExp.prototype.exec( string )
メソッド
正規表現のマッチングを試して、マッチした文字列全体とキャプチャリングした文字列を取得するためのメソッドが RegExp.prototype.exec( string )
メソッドです。
このメソッドは、マッチングが成功した場合は Array
オブジェクトを返します。 その Array
オブジェクトの第 0 要素はマッチした部分文字列全体です。 正規表現にキャプチャリングが含まれていた場合は、Array
オブジェクトの第 1 要素以降に、順番にキャプチャリングされた文字列が格納されます。 さらに、この Array
オブジェクトには index
プロパティと input
プロパティが定義され、それぞれの値は、正規表現が文字列にマッチした開始位置とマッチングの対象になった文字列全体です。
また、RegExp
オブジェクトの global フラグが true
であるならば、マッチした部分の最後の文字の次の文字の位置が、RegExp
オブジェクトの lastIndex
プロパティに保持されます。 同じ RegExp
オブジェクトを使って再び exec
メソッドを実行すると、そのときのマッチングは lastIndex
プロパティの値から再開されます。 よって、while
ループでマッチしなくなるまで繰り返す、ということが可能です。
なお、マッチしなかった場合には exec
メソッドは null
を返します。
例
// global フラグを true にした RegExp オブジェクト var re = /<(\d+),(\d+)>/g; var m; // マッチする部分がある限り繰り返す while( m = ( re.exec( "ab<32,43>cddd<faa>da<342,2>bcaaeabc" ) ) ) { // マッチした部分の開始位置 print( m.index ); // マッチした部分文字列全体 (Ruby などでは $& で参照できる) print( m.shift() ); // (第 0 要素だけを取り出している) // キャプチャされた部分 (Ruby などでは $1, $2, ... で参照できる) print( m.join( ", " ) ); // (元々の第 0 要素は既に取り出したので, 残りはキャプチャされた部分のみ) }
JavaScript でも、バージョンによっては RegExp['$&']
としてマッチした部分文字列全体を参照したり RegExp.$1
, RegExp.$2
, ... としてキャプチャされた部分を参照できたりしましたが、非推奨となっており、使わないようにした方がいいでしょう。 (ちなみに RegExp.$&
は基本的に構文エラーになってしまうので、RegExp['$&']
と書く必要がある。)
参考文献
- ECMAScript - Documentation (ECMAScript の仕様書)
- RegExp - MDN Docs
- 取説 正規表現 (nanto_vi さん)