JavaScript: 正規表現 match() と exec() の違い
JavaScript では、正規表現にマッチした文字列を取得するメソッドとして、 match() メソッドと exec() メソッドがあります。
このページでは、この2つのメソッドの違いを説明します。
オブジェクト、書式の違い
まず、「どのオブジェクトのメソッドか」という違いがあります。 match() メソッドは String オブジェクトのメソッドで、 exec() メソッドは RedExp オブジェクトのメソッドです。
ですから、書式はそれぞれ次のようになります。
// match()
文字列.match(正規表現)
// exec()
正規表現.exec(文字列)
取得できる結果の違い
次は、取得できる結果の違いについてです。
match() メソッドは、マッチした文字列を、配列としてまとめて取得できます。
一方、exec() メソッドは、一度に取得できるのは1つのマッチング結果だけです。 その代わり、サブマッチ文字列等の詳細な結果を取得できます。
つまり、マッチング文字列を得られれば十分なケースでは match() メソッドを使い、 詳細な結果を取得したい場合は exec() メソッドを使います。
ですから、通常の正規表現では match() メソッドで十分だと思います。
補足: マッチする文字列がない場合は、どちらのメソッドも「null」 を返します。
次は具体的なコード例を見てみます。
サンプルコード
match() メソッド
match() メソッドの場合は、マッチした文字列を配列としてまとめて取得できます。
下のコードの場合は配列 arr に結果が入っていますので、 後は配列 arr をループで回して内容を表示しています。
// 文字列
var str = "cat map cut bat cute cap";
// 正規表現
var ex = /c.t/g;
var arr = str.match(ex);
for (var i = 0, len = arr.length; i < len; i++){
console.log(arr[i]);
}
// 実行結果
cat
cut
cut
exec() メソッド
exec() メソッドの場合は、一度に1つのマッチング文字列、およびサブマッチング文字列等を取得できます。
マッチする文字列がない(なくなった)場合の戻り値が null なので、 exec() の結果が null になるまでループさせています。
// 文字列
var str = "〒 135-0064\n〒 105-7444";
// 正規表現
var ex = /(\d{3})-(\d{4})/g;
var arr = [];
while((arr = ex.exec(str)) != null){
console.log(arr);
console.log('マッチ文字列:', arr[0]);
console.log('lastIndex:', ex.lastIndex);
}
// 実行結果
Array [ "135-0064", "135", "0064" ]
マッチ文字列: 135-0064
lastIndex: 10
Array [ "105-7444", "105", "7444" ]
マッチ文字列: 105-7444
lastIndex: 21
exec() メソッドだからこそできること
通常は match() メソッドで十分だと思いますが、 exec() メソッドだからこそ、できることもありますので紹介します。
文字列 '123456789' から、「3桁の連続した数字」をすべて取得します。
つまり、123, 234, 345, 456, 567, 678, 789 を取得します。
match() メソッド
match() メソッドを使ってみると、次のようになります。
var str = '123456789';
var ex = /\d{3}/g;
var arr = str.match(ex);
console.log(arr);
// 実行結果
Array [ "123", "456", "789" ]
結果は、123, 456, 789 となり、すべてを取得することはできません。
取得した文字の次の文字からマッチングするのでこうした結果になります。
exec() メソッド
次は exec() メソッドを使ってみましょう。
var str = '123456789';
var ex = /\d{3}/g;
var arr = [];
while((arr = ex.exec(str)) != null){
console.log(arr);
ex.lastIndex -= 2;
}
// 実行結果
Array [ "123" ]
Array [ "234" ]
Array [ "345" ]
Array [ "456" ]
Array [ "567" ]
Array [ "678" ]
Array [ "789" ]
うまく取得できました。
ポイントは赤字部分の 「ex.lastIndex -= 2;」です。
RegExp オブジェクトの lastIndex プロパティには、マッチした文字列の直後の文字位置が入っています。 この値を「-2」することによって、次のマッチングする文字位置を変更できます。
exec() メソッドはこのような使い方もできます。