JavaScriptでとりあえず文字列に正規表現がマッチするかだけ調べたい・・・
そういう場合はRegExpやStringオブジェクトのテスト系の関数が便利です。
これは詳しいマッチ結果を返すものでなく、真偽値や最初のマッチ位置だけを返します。
ということで正規表現のテストができるメソッドをまとめて紹介
このページの目次
正規表現テスト系メソッドまとめ
そのテスト系のメソッドというのが次の2つ
- String.prototype.search
- RegExp.prototype.test
StringオブジェクトとRegExpオブジェクトにそれぞれテスト系メソッドが用意されてます。
これらの詳しい使い方やコード例は次の通り
String.prototype.search
まず初めはStringオブジェクトのsearchメソッド
これはStringオブジェクトに対して次のように正規表現オブジェクトを渡して使用します。
1 |
str.search(regexp) |
str がStringオブジェクトで、 regexp がテストするための正規表現オブジェクト
そしてこのメソッドの返り値についてですが、
- マッチすれば最初に見つかったインデックス、
- マッチしなかった場合は -1 の値
という返り値を返してきます。
このメソッドを使えば単純に正規表現がマッチするか調べることが可能です。
例えば次がsearchメソッドを使って正規表現のテストをしているコード例
1 2 3 4 5 6 7 8 |
var str = 'hogehoge'; var regexp = /(hoge){2}/; if(str.search(regexp) !== -1){ console.log('Matched regexp.'); }else{ console.log('NOT Matched regexp.'); } |
serachメソッドで -1 が返ってくるかどうかで判定ができます。
このメソッドを使う利点はmatchメソッドより高速な所ですね。
細かな情報はいらないからマッチするかどうかだけ調べたいときに便利だと思います。
RegExp.prototype.test
これは文字通り正規表現のテストをするためのメソッド
次のようにRegExpオブジェクト regexObj に対してテストする文字列 str を渡して使用します。
1 |
regexObj.test(str) |
そしてこのメソッドの返り値についてですが、
- マッチした場合はtrue
- マッチしない場合はfalse
というように単純に真偽値だけを返すメソッドとなってます。
なのでsearchメソッド同様に正規表現のテストに利用可能です。
例えば次は先ほどのsearchメソッドの例をtestメソッドに置き換えたコード例
1 2 3 4 5 6 7 8 |
var str = 'hogehoge'; var regexp = /(hoge){2}/; if(regexp.test(str)){ console.log('Matched regexp.'); }else{ console.log('NOT Matched regexp.'); } |
こういう風にRegExp側からでも正規表現のテストはできます。
以上がRegExpのtestメソッドの使い方
こちらは真偽値を返すのでsearchメソッドよりも使い勝手がいいかもしれません。
マッチ系の関数との比較
今紹介したテスト系メソッドとは違い、詳しいマッチ結果を返すメソッドもあります。
それが次の2つのメソッド
- String.prototype.match
- RegExp.prototype.exec
matchメソッドは検索系のメソッドとしておなじみですよね。
これらのメソッドの使い方については次の記事で詳しく解説しました。
ちなみにexecメソッドはRegExpオブジェクト版のmatchメソッドのようなものです。
それで気になるのがテスト系メソッドとどれだけ実行速度が違うのかということ
当然処理が複雑な分だけ、 match や exec の方が遅くなります。
その差がどれほどあるのか気になったので、実際に調べてみました。
searchメソッドとmatchメソッドの比較
Stringオブジェクトのこの2つをまずは比較してみます。
検証に使用したのは次のようなコード
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** fizzbuzzが1000回繰り返される文字列 */ var str = "fizzbuzz".repeat(1000); /** strにマッチさせる正規表現オブジェクト */ var regexp = /fizz(buz+)/; var start = performance.now(); for(j = 0; j < 1000000; j++){ // 次の2つのコードのいずれかを実行 //str.search(regexp); //str.match(regexp); } var end = performance.now(); var time = (end - start).toFixed(3); |
このコードでは処理時間を正確に計測する方法で紹介したように performance を使っています。
これを使うことでミリ秒まで計測することが可能です。
そしてこのコードをそれぞれ10回繰り返し、その平均値を求めてみました。
matchメソッドとsearchメソッドの平均処理時間の結果は次の表の通り
matchメソッド | searchメソッド | |
---|---|---|
平均処理時間 | 107.0ms | 59.7ms |
やはり最初のインデックスだけを返す分だけsearchメソッドの方が速くなるようです。
単純にマッチするかどうかだけを知りたい場合は match より search の方が高速になりますね。
execメソッドとtestメソッドの比較
お次はRegExpオブジェクトの exec と test の比較
ここでも検証用に次のようなコードを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** fizzbuzzが1000回繰り返される文字列 */ var str = "fizzbuzz".repeat(1000); /** strにマッチさせる正規表現オブジェクト */ var regexp = /fizz(buz+)/; var start = performance.now(); for(j = 0; j < 1000000; j++){ // 次の2つのいずれかを実行 //regexp.test(str); //regexp.exec(str); } var end = performance.now(); var time = (end - start).toFixed(3); |
先ほどの match と test の部分を置き換えただけです。
こちらも10回繰り返して処理時間の平均値を求めてみました。
その結果は次の表の通り
execメソッド | testメソッド | |
---|---|---|
平均処理時間 | 106.4ms | 49.9ms |
当然無駄な処理が少ない分だけtestメソッドの方が速くなります。
Stringオブジェクトの search と比べると test の方が若干速いのかな?という感じ
まあ正規表現のテストをするだけなら search か test を使った方が高速に処理できますね。
正規表現の関連記事
正規表現については次の記事でも色々紹介・解説してます。
JavaScriptで正規表現を表す2つの方法とパフォーマンス的な違い
正規表現の内部処理が分かる便利ツールregex101を使ってみた
ここまでのまとめ
ということでテスト系のメソッドの簡単なまとめ
- String.prototype.search
文字列に対して str.search(regexp) のように正規表現オブジェクトを渡して使う
もしマッチすれば最初のインデックス、しなければ -1 を返す - RegExp.prototype.test
正規表現オブジェクトに対して regexp.test(str) のように文字列を渡して使う
もしマッチすれば true 、マッチしなければ false を返す
普通は正規表現というとmatchメソッドを使う場合が多いと思います。
ですが最初のインデックスやマッチするかだけ知りたいならこちらを使う方が高速です。
以上JavaScriptの正規表現テスト系のメソッドをまとめてみました。
ではではヾ(^_^) byebye!!