Rubyで正規表現を使うならRegexpクラスを利用します。正規表現と聞いて、特殊な文字を使った難しい検索方法と思っている方も多いのではないでしょうか。Rubyを使うことで短く読み易いプログラムが書けますが、そのようなプログラムを実践しているベテランエンジニア方は正規表現を活用しています。
このように正規表現はRubyに欠かせない仕組みです。今回はRubyの正規表現を学びたいと考えている方にRegexpクラスの仕組みと使い方について解説します。
Rubyで正規表現を使うには
効率よく文字列を処理するプログラムを書くためには、正規表現の利用が欠かせません。そしてRubyで正規表現を利用する仕組みがRegexpクラスです。
Rubyのスキルアップには正規表現への理解が欠かせません。そこでまずは正規表現について簡単に解説します。
正規表現とは
正規表現とは文字列の集合をメタ文字と呼ばれる意味のある文字やそれを組み合わせた文字列で表現する方法です。複雑な文字列を簡単な文字の組み合わせで表現できることから、文字の検索やチェックによく使われます。
ただしメタ文字の組み合わせで表現できる範囲が広く、解説するとかなりの分量になってしまいます。例えば正規表現の使い方を解説した「O’Reillyの詳説 正規表現 第3版」は528ページもあるほどです。そのためプログラミングを始めたばかりの方にとっては難しいと感じるかもしれません。
しかし正規表現はRubyの短く読み易いプログラムと相性が良く、Rubyのプログラムの中でよく使われるので早めに習得することをお勧めします。
正規表現によるパターンマッチング
プログラムの中で正規表現が使われるのは文字列のパターンマッチングです。パターンマッチングとは、長い文字列の中から特定の文字の組み合わせの有無をチェックする方法で、出現位置の検索などにも使われます。
ただし検索に使われる文字列が1つだとは限りません。複雑なケースもよくあります。しかし、正規表現を利用することで複雑な文字の組み合わせを短い文字列で表現できます。
そのためRubyで文字列を操作するプログラムを記述する場合は、必ずと言っていいほど正規表現が使われます。
Rubyの正規表現はRegexpクラスで
Rubyのプログラムを構成する要素は何らかのクラスに所属していますが、今回紹介している正規表現はRegexpクラスで定義されています。
Regexpクラスを利用することで正規表現による文字列のパターンマッチングだけでなく、検索をサポートするメソッドも利用できます。Rubyで正規表現を使うならRegexpクラスの使い方をマスターしてください。
Regexpクラスの使い方
先ほど紹介したようにRubyで正規表現を使うにはRegexpクラスを利用します。まずは正規表現のオブジェクトの作り方を理解しましょう。
次からRegexpクラスを利用するために必要な正規表現オブジェクトの作り方と使い方を解説します。
スラッシュで囲んだ形式
Regexpクラスで正規表現を使う際によく利用されるのがスラッシュで囲んだ形式です。正規表現では検索パターンとなる文字列と特別な意味を持つメタ文字を合わせて使用します。このような文字列をスラッシュで囲むとRegexpクラスのオブジェクトとして扱われるので検索などに利用できます。
スラッシュで囲んだ正規表現
/パターン/
スラッシュで囲んだ正規表現を使った例
str = "2021admin" if /2021./ =~ str then p "2021で始まる文字列です" else p "一致しません" end
この例では文字列strが、正規表現「/2021./」にマッチしていれば”2021で始まる文字列です”を、マッチしていなければ”一致しません”を表示します。なお正規表現「/2021./」は「2021という文字列で始まる文字列」という意味です。また「=~」はRegexpクラスの演算子で正規表現によるマッチをチェックします。
正規表現オブジェクトを利用する
newメソッドを用いてRegexpクラスの正規表現オブジェクトを作成し、このオブジェクトの正規表現を用いたプログラムも作れます。正規表現オブジェクトを用い、先ほど紹介したスラッシュで囲んだ正規表現を変数名で置き換えた例を次に紹介します。
正規表現オブジェクトを用いた例
str = "2021admin" obj = Regexp.new(/2021./) if obj =~ str then p "2021で始まる文字列です" else p "一致しません" end
この例は先ほど紹介したスラッシュで囲んだ正規表現「/2021./」と同じ正規表現のオブジェクト「obj」を作り、「=~」演算子でマッチしているかをチェックするプログラムです。
Regexpクラスのメソッドを利用する
先ほどの例で用いた「=~」演算子もRegexpクラスのメソッドですが、他ものメソッドが定義されており正規表現を用いた検索などで利用できます。例えば、「=~」演算子はmatch?メソッドで置き換えることが可能です。
正規表現とmatch?メソッドを用いた例
str = "2021admin" obj = Regexp.new(/2021./) if obj.match?(str) then p "2021で始まる文字列です" else p "一致しません" end
Regexpクラスのメソッドの使い方
正規表現は簡単な文字列で複雑なパターンの検索が可能です。そして先ほど紹介したようにRubyでは正規表現をRegexpクラスのオブジェクトとして利用できます。
さらにRegexpクラスには正規表現を利用するためのメソッドが幾つか用意されており、そのメソッドを使うことで正規表現によるマッチングなどが可能です。次から代表的なメソッドの使い方を紹介します。
match?メソッドを使う
正規表現は長い文字列の中から特定のパターンの文字列を検索するパターンマッチングによく利用されます。そしてRubyで正規表現によるパターンマッチングに使われるメソッドがmatch?です。
match?メソッドは、Regexpクラスのメソッドでマッチしていればtrueを、していなければfalseを返します。使い方は正規表現オブジェクトに「.」で接続して引数に検索対象の文字列および検索開始位置を指定します。なお検索開始位置は省略可能です。
mactch?メソッドの使い方
正規表現オブジェクト.match?(文字列, 検索開始位置)
matchメソッドの例
if /2021./.match?(str) then p "変数strの内容は2021で始まる文字列です" else p "一致しません" end
=~演算子を使う
=~演算子は、正規表現の検索パターンが指定した文字列に含まれているかをチェックし、マッチしていればその位置を、マッチしていなかったらnilを返します。
先ほど紹介したmatch?メソッドはマッチの有無のチェックだけでしたが、=`演算子では文字の位置を調べられるので、文字列を切り出す処理などに使われます。
Regexpクラスを利用し文字を切り出す処理の例
str = '' p1 = /src="/ =~ str p2 = /" \/>/ =~ str if ( p1 != nil ) && ( p2 != nil ) then out = str[p1+5, p2-p1-5] puts out # /assets/home/house@2x.png end
文字列strの中から「src=”」と「” />」にマッチする位置をp1とp2に代入し、それらがnilでなければその位置を使って文字列を切り出す例です。
正規表現との一致をチェックする
Regexpクラスの===演算子の左側に正規表現オブジェクトを、また右側に文字列を記述することで、文字列が正規表現とマッチするかをチェックします。そしてマッチしていればtrueを、マッチしていなければfalseを返します。
===演算子の使い方
正規表現オブジェクト === 文字列
正規表現の「/\A[0-9]{4}[a-z]{2}/」は、文字列の最初から4文字が数字で、続く2文字が小文字のアルファベットという意味です。
そのためこの例を実行するとstrに代入された「2021ab」が評価され、マッチしているので「一致」と表示します。もしstrが「ab2021」や「20201abc」なら、マッチしていないため「不一致」と表示されます。
まとめ
これまで紹介したようにRubyのRegexpクラスを利用することで正規表現を使った高度なマッチングが可能です。具体的には正規表現を/で括るかRegexp.new()で正規表現オブジェクトを作り、Regexpクラスのメソッドを適用して検索などに利用します。
正規表現は簡単な文字の組み合わせで複雑なパターンが作れますが、機能が豊富な分覚えるのも大変です。しかし、使いこなせるとRubyらしい簡潔なプログラムが作れるので、スキルアップを目指すなら正規表現の使い方をマスターしましょう。