3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【JavaScript】文字列の配列で正規表現にマッチするものを含むか判定する方法

Last updated at Posted at 2017-10-08

以前に書いた【JavaScript】文字列の配列で正規表現にマッチするものだけを取り出す方法という記事では、bindメソッド (Function.prototype.bind1)とビルトイン関数をうまく活用した例を紹介したつもりのですが、後日その例が良くないこと(bindなしでかつ可読性も高い書き方があった)に気付きました。
その後もbindメソッドをうまく活用した例を考えた続けていたところ、今度こそ(?)は良い例を見つけました。

今回はFunction.prototype.bind1, Array.prototype.some2, RegExp.prototype.test3を組み合わせ、標題のことを実現する例を紹介します。

サンプル

まずはbindなしで

Node.jsではprocess.argvによって、コマンドライン引数が格納された配列(正確には3番目の要素から格納される4ので、process.argv.slice(2))を受け取ることができるので、これを用いた例を紹介します

test01.js
const hasVersion = process.argv.slice(2).some(RegExp.prototype.test, /^(-v|--version)$/i);
console.log(hasVersion);

これは、コマンドライン引数に-vまたは--versionが指定された場合にtrue, 指定されなかった場合にfalseを表示する例となっています。
正規表現にフラグi(大文字小文字の区別なし)を指定しているので、例えばコマンドライン引数に-Vが指定された場合にもtrueが表示されます。

実行結果は以下の通りです

$ node test01
false
$ node test01 -v
true
$ node test01 -V
true
$ node test01 --version
true
$ node test01 --readonly --VERSION
true

bind登場

-vまたは--versionの有無の判定の他に、-roまたは--readonlyの有無の判定もしたいといったケースも考えられると思います。
引数に正規表現を指定すると、コマンドライン引数にマッチするものがあるか判定する関数があると便利そうです。
以下の例では checkArgs がそのような関数となっていて、bindを用いて生成されています。

test02.js
// const checkArgs = Array.prototype.some.bind(process.argv.slice(2), RegExp.prototype.test);
const checkArgs = [].some.bind(process.argv.slice(2), /./.test);

console.log('Version:', checkArgs(/^(-v|--version)$/i));
console.log('ReadOnly:', checkArgs(/^(-ro|--readonly)$/i));

[]/./は、Array.prototype.someRegExp.prototype.testを呼び出すためだけにあるリテラルとなっています(詳しくは以前に書いた記事を参照)

実行結果は以下の通りです

$ node test02
Version: false
ReadOnly: false
$ node test02 -v
Version: true
ReadOnly: false
$ node test02 -ro -v
Version: true
ReadOnly: true
$ node test02 --readonly --VERSION
Version: true
ReadOnly: true
$ node test02 --version --ReadOnly
Version: true
ReadOnly: true
$ node test02 --version -Ro
Version: true
ReadOnly: true

また、const宣言を除けばECMAScript 6以上の仕様は使っていないので、Internet Explorer 11でも動作しました。

IE11のコンソール上での実行例

var checkArgs = [].some.bind(['Red', 'Green', 'Blue', 'White'], /./.test);
checkArgs(/^White$/i);
checkArgs(/^R/i);
checkArgs(/Black/i);

実行結果は以下の通りです

ie11_some_bind_regexp.png

配列のindexOf, includesメソッドよりも良いところ

今回紹介した方法がindexOfメソッド(Array.prototype.indexOf5), includesメソッド(Array.prototype.includes6)と比べて良いところをまとめました

  • 大文字小文字の区別をしない指定(フラグi)やOR検索といった正規表現の機能を利用できる
  • ECMAScript 5までの仕様のみ利用している
    • includesメソッド(特定の要素が配列に含まれているかどうかを真偽値で返す6)はES5までに入っていない

参考文献

  1. Function.prototype.bind() - JavaScript | MDN 2

  2. Array.prototype.some() - JavaScript | MDN

  3. RegExp.prototype.test() - JavaScript | MDN

  4. Node.jsでコマンドライン引数を取得する - Qiita

  5. Array.prototype.indexOf() - JavaScript | MDN

  6. Array.prototype.includes() - JavaScript | MDN 2

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?