[JavaScript] うろ覚えだった RegExp オブジェクト をしっかり学習した

RegExp は 正規表現(Regular Expression)の略。以下、参考サイト。

RegExpオブジェクトの中身は?

RegExpオブジェクトのプロパティには直前のマッチングに関する情報が入る。じゃあ何が入っているのか?

//とりあえずなにもせずに調べてみる
function dump( obj ){
  var str = '';
  for(var k in obj){
    str += k + "("+typeof(obj[k]) + ") | " + obj[k] + "\n";
  }
  document.write( str );
}
dump( RegExp );

結果

input(string) | message.Reload to activate window console
multiline(boolean) | false
lastMatch(string) |  
lastParen(string) |
leftContext(string) | message.Reload to activate window
rightContext(string) | console
$1(string) |
$2(string) |
$3(string) |
$4(string) |
$5(string) |
$6(string) |
$7(string) |
$8(string) |
$9(string) |

とりあえずいろいろなプロパティがあるのが分かる

"あいうえおかきくけこ".match(/([あか]).(.)/g);
dump( RegExp );

結果

input(string) | あいうえおかきくけこ
multiline(boolean) | false
lastMatch(string) | かきく
lastParen(string) | く
leftContext(string) | あいうえお
rightContext(string) | けこ
$1(string) | か
$2(string) | く
$3(string) |
$4(string) |
$5(string) |
$6(string) |
$7(string) |
$8(string) |
$9(string) |
  • RegExp.input : 調べる文字列
  • RegExp.multiline : (略)
  • lastMatch : 最後にマッチングしたテキスト
  • lastParen : 最後にマッチングしたサブ表現のテキスト。
  • leftContext : 最後のマッチングの前のテキスト
  • rightContext : 最後のマッチングの後ろのテキスト
  • $1~9 : キャプチャの中身

※Strimg.match( "String" ) というように文字列を入れると RegExpオブジェクトのプロパティ は変化しない…と思ったけど違った。FireFox3では、match に入れた引数が正規表現、または正規表現として解釈することが可能な文字列の場合にマッチした場合にはRegExpオブジェクトのプロパティが変化する。Chrome8 は引数に関係なくマッチすればRegExpオブジェクトのプロパティが変化する。ブラウザ依存。

RegExpインスタンスのプロパティ

var r = new RegExp(); // var r = /(?:)/ と同じ
var arr = [];
arr.push( r );
arr.push( r.constructor );
document.write(arr.join("\n"));

結果

/(?:)/
function RegExp() {
    [native code]
}
var r = new RegExp( 'R', 'igmy' ) ;
var a = [];

a.push(".source : " + r.source);
a.push(".ignoreCase : " + r.ignoreCase);
a.push(".global : " + r.global);
a.push(".sticky : " + r.sticky); // FireFox 3 のみ
a.push(".multiline : " + r.multiline);
a.push(".lastIndex : " + r.lastIndex);

document.write(a.join("\n"));

結果

.source : R
.ignoreCase : true
.global : true
.sticky : true
.multiline : false
.lastIndex : 0
  • .source : 正規表現の中身
  • .ignoreCase : iフラグの有無
  • .global : gフラグの有無
  • .multiline : mフラグの有無
  • .sticky : yフラグの有無(FireFox 3 限定?みたいなので使う機会はなさそうだけど…) 行ごとのマッチングが可能
  • .lastIndex : デフォの値は 0 。以下のメソッドを参照。

RegExpインスタンスのメソッド

RegExp.test()

マッチするかどうかを確かめるメソッド。マッチするときは ture 、しないときは false を返す。また、gフラグが立っているときは自身のlastIndexプロパティの値が変わる。

var r = new RegExp( '正規表現', 'g' ) ;
var a = [];
var b = [];

a.push( r.test() ); // false
b.push( r.lastIndex ); // 0

RegExp.input = '正規表現'; // r.input じゃダメ
a.push( r.test() ); // true - testメソッドの引数が空のときは RegExp.input の値が使われる。RegExp.input は直前のパターンマッチングに使用した文字列
b.push( r.lastIndex ); // 4

a.push( r.test("引数にStringを入れた場合はそれに対して正規表現がマッチするかどうかを調べる。正規表現\n") ); // true
b.push( r.lastIndex ); // 26 - gフラグが false の場合は lastIndex は常に 0

a.push( r.test() ); // true - gフラグが true ならば、lastIndexの値は正規表現に最後にマッチングした文字列のすぐ後ろの文字の位置の値が入る
b.push( r.lastIndex ); // 45

a.push( r.test("gフラグが true ならば、lastIndexプロパティの値位置から正規表現のマッチングが始まる。") ); // false
b.push( r.lastIndex ); // 0 - false だった場合は lastIndex は 0 に戻る

a.push( r.test() ); // true
b.push( r.lastIndex ); // 26 - なぜに 26 ?
document.write( RegExp.input ); // false の場合は .input の値は変化しないようだ

a.push("\n");
document.write(a.join());
document.write(b.join());

結果

引数にStringを入れた場合はそれに対して正規表現がマッチするかどうかを調べる。正規表現
false,true,true,true,false,true,
0,4,26,45,0,26

RegExp.exec(), RegExp()

RegExp() と RegExp.exec() は同じ。

var r = new RegExp( '([A-Z])([A-Z])', 'g' ) ;

dump(r.exec("---AB---CD---"));
document.write(r.lastIndex);
document.write("\n\n");

dump(r());
document.write(r.lastIndex);

document.write("\n\n" + r() );

結果

0(string) | AB
1(string) | A
2(string) | B
index(number) | 3
input(string) | ---AB---CD---
5

0(string) | CD
1(string) | C
2(string) | D
index(number) | 8
input(string) | ---AB---CD---
10

null

String.match() よりも詳細な情報を調べられる。返り値は以下の内容を持つ配列。

  • 0 : マッチした部分
  • 1 : 最初にマッチしたキャプチャ
  • 2 : 2番目にマッチしたキャプチャ
  • 3 以降 : 3以降のキャプチャもある。String.match() と違い数に制限は無い…と勘違いしてたけどキャプチャの数が9までなのはRegExpだった orz
  • index : マッチした部分の最初の位置。 index + 0.length = lastIndex
  • input : 調べた文字列

.test() と同様に lastIndex プロパティも変化する。

グローバルオプションがOFFの場合は lastIndexプロパティが 0 のまま変化しないため、2回目の execメソッドが1回目と同じ結果となる。

Share
関連記事