こんにちは、ライターのマサトです!
今回は、JavaScriptで正規表現を使うための「RegExp」オブジェクトについて学習をしましょう!
正規表現を使いこなせるようになると、対象の文字列検索や抽出といったテクニックをとても効率化できるのでオススメです。
そこで、この記事では…
・RegExp(正規表現)とは?
・RegExpの使い方
という基本的な内容から学習を進めていき、
・正規表現の特殊文字を使う方法
・RegExpで置換する
・RegExpのメソッドについて
・正規表現リテラルとの違い
などの応用的な使い方に関しても解説していきます。
この記事で、JavaScriptの「RegExp」オブジェクトをしっかり学習して自分のスキルアップを目指しましょう!
RegExp(正規表現)とは?
まず最初に、「RegExp」オブジェクトの基本から学習していきましょう!
JavaScriptで正規表現を扱えるようにするためには、まず「RegExp」オブジェクトを作成する必要があります。
(正規表現リテラルを使う方法もありますが、これに関しては記事後半で解説します)
このRegExpオブジェクトを利用することで、正規表現による検索や置換など文字列操作を自在に扱えるようになるわけです!
また、正規表現を便利に扱えるメソッドも標準で用意されているので、本記事で合わせて解説を致します!
RegExpの使い方
この章では、RegExpを使う上で基本的な知識を身に付けていきましょう!
一般的な構文や書き方から変数に代入する方法、実際の使い方などについて学んでいきます。
基本的な構文と書き方について
まずは、「RegExp」オブジェクトの一般的な構文から見ていきましょう!
var reg = new RegExp( パターン, フラグ );
「RegExp」コンストラクタをnewすることで、JavaScriptで正規表現が扱えるRegExpオブジェクトを生成することができます。
引数の「パターン」には一般的な正規表現を指定し、「フラグ(g,i,mなど)」を指定すればOKです!(フラグについては後述します)
ただし、正規表現の文字列指定には注意が必要です!
正規表現で一般的に使う「\d」「\w」などの「\(バックスラッシュ)」はエスケープ処理と判断されてしまいます。
そこで、対応策として「\\d」や「\\w」のように2重で記述するわけです!
new RegExp('\d\d'); //これは間違い new RegExp('\\d\\d'); //これは正解!
このように、バックスラッシュを使う場合は2重に記述することを覚えておきましょう。
より詳しいエスケープ処理については、次の記事でさまざまな事例と一緒に解説しているのでぜひ参考にしてみてください!
RegExpを変数に代入する
次に、正規表現パターンを変数に代入する方法について見ていきましょう!
これは一般的な値を変数に代入する方法と同じやり方で問題ありません。
次のサンプル例を見てください!
var pattern = 'user1\\d\\d'; var reg = new RegExp( pattern );
この例では、文字列の正規表現を変数「pattern」に代入していますね。
これにより変数「pattern」は正規表現として扱えるので、RegExpの引数にそのまま指定できるというわけです。
この方法を活用すれば、さまざまな正規表現パターンを動的に差し替えることも可能になります。
また、外部データとして正規表現をRegExpの引数に指定することもできます。
「match」を使って文字列を抽出する方法
「RegExp」オブジェクトの基本を抑えたところで、実際の活用事例を見ていきましょう!
ここでは「match」メソッドを使って、特定の文字列を正規表現で抽出してみます。
例えば、複数の「ユーザーID」を文字列で受け取り、特定のIDだけを抽出する例を見てみましょう。
var users = 'user-g,user-a,user-k,user-d,user-z,user-m'; //a〜cの値を持つユーザーIDを抽出する var pattern = new RegExp( 'user-[a-c]' ); var result = users.match( pattern ); console.log( result );
実行結果
["user-a"...]
このサンプル例では、RegExpコンストラクタの引数として「user-[a-c]」という文字列パターンを作成し、a〜cの値をもつIDだけを抽出しているのが結果からも分かりますね。
「match()」メソッドは、その名の通りパターンと最初に一致した文字列を抽出するという機能を持っているのです。
これにより、例えば大量にある文字列データの中から欲しい情報だけを瞬時に取り出すようなプログラムを効率よく書くことができます。
「match()」メソッドについては、次の記事で豊富なサンプル事例と一緒に応用的な活用技も学習できるので、ぜひ参考にしてみてください!
正規表現の特殊文字を使う方法
正規表現では、さまざまな特殊文字を組み合わせることで複雑な条件を指定することが可能です。
例えば、「\w」は英数字を意味しており「\s」は改行やスペース、「\d」は数字を表しているのです。
次の例を見てください!
/user\d/
「user」のあとに続けて「\d」を記述していますよね?
「\d」は数字を表している特殊文字でした。(0~9まで)
つまり、「user0」~「user9」までの文字列を表している正規表現パターンという意味になります。
このような特殊文字はたくさんあるのですが、大きく分けると4つのパターンに分類できます。
これらの活用方法について次の記事で体系的にまとめているので、ぜひ参考にしてみてください!
RegExpで置換する
この章では、RegExpを使って対象となる文字列を置換する方法について見ていきましょう!
主に、「replace()」を使った手法とフラグを活用した抽出方法についても学んでいきます。
「replace」を使って置換を行う方法
今度は、同じ文字列を使って「置換」を試してみましょう!
「置換」を実現する最も簡単な方法としては、「replace()」メソッドを使うのが良いでしょう。
次のサンプル例を見てください。
var users = 'user8,user2,user12,user123,user24,user9'; //1〜3の数値を持つユーザー名を抽出する var pattern = new RegExp( 'user[1-3]' ); //抽出した文字列を「new-user」に置換する var result = users.replace( pattern, 'new-user' ); console.log( result );
実行結果
user8,new-user,user12,user123,user24,user9
このサンプルでは正規表現パターンを「user[1-3]」とし、文字列内で「1〜3の数値を持つユーザー名」を抽出しているのが分かりますね。
そして「replace」メソッドを使って、最初に一致した対象文字列を「new-user」という文字列に置換を行っているのが実行結果から分かります。
ちなみに、「置換」についてさらなる知識を深めたいという方は、次の記事で豊富な事例と一緒にさまざまな手法を解説しているので参考にしてみてください!
「g」フラグにによるグローバルサーチを行う方法
「match」や「replace」を使った手法では、最初に一致した文字列を取得できるわけですが、1回の実行で一致するすべての文字列を取得する方法もあります。
それは、RegExpの第2引数に指定する「g」フラグです。
「g」はグローバルサーチの略称なのですが、これを付与するだけで正規表現パターンに合致する対象文字列をすべて抽出するという意味になるわけです。
次のサンプル例を見てください!
var users = 'user22,user2,user5,user123,user24,user9'; //1〜5の番号を持つユーザーIDをすべて抽出する var pattern = new RegExp( 'user[1-5],', 'g' ); var result = users.match( pattern ); console.log( result );
実行結果
["user2,", "user5,"]
この例では、正規表現のパターンを「user[1-5],」としており、1〜5までの番号を持つユーザーIDで最後に「, (カンマ)」で終わる文字列を抽出しています。
そして、RegExpの第2引数には「g」フラグを付与していることで、対象となる文字列をすべて抽出できているのが分かりますね。
このように、「g」フラグを活用すると必要な情報を1回の実行で取得できるので、プログラムの効率化にも繋がる重要な機能と言えるでしょう。
RegExpメソッドについて
これまでのサンプルで、「match」や「replace」などのメソッドを組み合わせて対象の文字列を抽出してきました。
実は、RegExpオブジェクトにはデフォルトで用意されている組み込みメソッドがあり、これらのメソッドを活用することでも同じようなことを実現できます。
そこで、特に利用頻度が高いものを2つご紹介しますので、ぜひ使い方を覚えて有効に活用できるようにしましょう!
「exec」で最初に一致した文字列を抽出する方法
まず、最初に「exec」メソッドの使い方から学習を始めましょう!
次のサンプル例を見てください。
var str = 'user123, user145, user245, user121'; var pattern = new RegExp(/user1\d\d/, 'g'); //execメソッドを使って抽出した文字列を表示 console.log( pattern.exec(str)[0] );
実行結果
user123
この例では、正規表現パターンとして「100番台のユーザーID」を抽出するように指定しているのが分かります。
そして、そのパターンを「exec()」メソッドを使い「 . (ドット)」で連結させて、引数に対象の文字列を指定します。
すると、返り値として配列データを受け取り、0番目の要素にパターンと一致した文字列を取得することができます。
注意するべき点として、パターンに「g」フラグを適用しているにも関わらず、最初に一致した文字列しか抽出していない点です!
実は、execメソッドは1回の実行で1つの該当する文字列しか抽出できない仕様になっており、続けて再実行することで次に該当する文字列を抽出してくれます。
この仕組みを利用すると、例えばWhile文などの繰り返し構文を利用することで、すべての該当する文字列を抽出するプログラムを作成できます!
var str = 'user123, user145, user245, user121'; var pattern = new RegExp(/user1\d\d/, 'g'); var result = true; //resultがnullになったら繰り返し終了 while(result) { result = pattern.exec(str); console.log(result); }
実行結果
["user123", index: 0, input: "user123, user145, user245, user121", groups: undefined] ["user145", index: 9, input: "user123, user145, user245, user121", groups: undefined] ["user121", index: 27, input: "user123, user145, user245, user121", groups: undefined] null
この例では、先ほどのパターンとまったく同じですが、while文で繰り返し処理を行うことで、次々と該当する文字列を取得できているわけです。
そして、execメソッドは合致する文字列が無くなるとnullを返すので、上記サンプルのようにWhile文で簡単に繰り返し処理が作れるのです。
「test」でtrue / falseを取得する方法
execメソッドは該当する文字列を返してくるのに対して、testメソッドは該当する文字列の有無によって「true / false」を返してくれるメソッドになります。
次のサンプルを見てください!
var str = 'user123, user145, user245, user121'; var pattern = new RegExp(/user1\d\d/, 'g'); console.log( pattern.test(str) );
実行結果
true
使い方はexecメソッドと同じで、正規表現パターンに「testメソッド」を繋げて実行すればOKです。
このサンプルでは、100番台のユーザーIDが文字列の中にあるかどうかをチェックしており、実際には存在しているので結果的に「true」を返しているのが分かります。
また、このtestメソッドも繰り返し処理を実行することで、次に該当する文字列を抽出できるためexecメソッドのように該当する文字列をすべて取得することができます。
正規表現リテラルとの違い
ここまで「RegExp」コンストラクタを使った正規表現のプログラミングを学習してきましたが、JavaScriptにはもう1つ違った書き方があります。
それが「正規表現リテラル」という書き方です!
なんだか難しそうな名称ですが、実はとても簡単に記述できる方法でもあります。
一般的な書き方は次のとおりです!
var str = '126,242,123,456'; //「正規表現リテラル」で100番台の数値をすべて対象にする var pattern = /1\d\d/g; var result = str.match( pattern ); console.log( result );
出力結果
["126", "123"]
このサンプルを見ると分かりますが、正規表現リテラルで記述する場合は「/1\d\d/g」のように正規表現をそのまま記述しているのが特徴です。
そのため、RegExpコンストラクタを使わなくても良いので、とてもシンプルに「正規表現パターン」を記述できていることが分かりますね。
注意するべき点としては、正規表現リテラルによる記述では文字列を指定するわけではないので「エスケープ処理」を考える必要がありません。
次のサンプル例を見てください!
//正規表現リテラルの場合 var re1 = /\d\d\d/g; //RegExpコンストラクタの場合 var re2 = new RegExp('\\d\\d\\d', 'g'); console.log(re1); console.log(re2);
実行結果
/\d\d\d/g /\d\d\d/g
実行結果を見ると、どちらの書き方もまったく同じ正規表現パターンを指定していることが分かりますね。
つまり、RegExpコンストラクタを使う場合には「エスケープ処理」が必要ですが、正規表現リテラルの場合はパターンをそのまま指定すれば良いわけです。
この2つの違いをしっかりと認識して、混乱しないように注意しましょう!
まとめ
今回は、JavaScriptで正規表現を扱うための「RegExp」オブジェクトについて学習しました!
最後に、もう一度ポイントをおさらいしておきましょう!
・RegExpオブジェクトを作成することでJavaScriptによる正規表現が扱える
・文字列で正規表現パターンを指定する場合はエスケープ処理に注意する
・「match」「replace」と組み合わせると、抽出・置換を実行できる
・「g」フラグを付与すると、すべてを対象にできる
・RegExpの組み込みメソッドとして「exec」「test」がよく使われる
・正規表現リテラルとRegExpコンストラクタの違いに注意する
上記ポイントを踏まえたうえで、自分でも実際にプログラミングしてどのような結果を得られのか確認するようにしておきましょう!