正規表現で一致した文字列を取得したい場合、Rubyでは「match」メソッドを利用することが可能です。
本記事では、matchメソッドの概要から実際の使い方までサンプルコードを掲載しながらご紹介していきます。
目次
matchメソッドとは
matchメソッドはStringクラスより提供されているメソッドです。
指定した文字列と引数で指定した正規表現がマッチするかを確認することが可能です。
基本構文
matchメソッドは下記の記述方法で使用します。
文字列.match(正規表現)
文字列が正規表現にマッチした場合、MatchDataオブジェクトが返却され、マッチしなかった場合には「nil」が返却されます。
文字列の開始位置を指定する
マッチする文字列の開始位置を指定するには第2引数に整数値を指定します。
文字列.match(正規表現, 開始位置)
例えば「やま」で始まる2番目以降の名字を取得したい場合下記のように記述します。
"やまだ やまもと やまうち".match(/やま.+/, 2)
実行してみると下記の文字列が取得出来ます。
"やまもと やまうち"
第2引数で2つ目の該当文字列から取得すると指定されているため、「やまだ」の文字列は取得されない結果となります。
ブロック指定
ブロック指定を利用するとマッチした場合には実行し、マッチしなかった場合には実行しない処理を記述することが可能です。
文字列.match(正規表現, 開始位置) {|m|処理}
例えば上記のサンプルでマッチした場合のみ、取得出来た文字列をコンソール出力したい場合には下記のような記述となります。
"やまだ やまもと やまうち".match(/やま.+/, 2) { |m| p m[0] }
実行結果が下記となります。
"やまもと やまうち"
反対に下記のようにマッチしない文字列を指定した場合には、コンソールには何も出力されません。
"やまだ やまもと やまうち".match(/たか.+/, 2) { |m| p m[0] }
matchメソッドを使用したRubyのサンプルプログラム
概要を確認出来たところで、実際にmatchメソッドを利用していくつかの文字列取得を実施していきます。
指定した文字列が含まれる
指定した文字列が含まれる場合、文字列を抽出するには下記のように記述することが出来ます。
str = "さるとりいぬ" result = str.match(/.+とり.+/) p result[0]
実行結果が下記です。
"さるとりいぬ"
サンプルでは「とり」という文字列が含まれる場合前後全ての文字列を抽出するように指定しています。
例えば「とり」より前の文字列だけを抜き出したい場合には下記のような記述となります。
str = "さるとりいぬ" result = str.match(/.+とり/) p result[0]
実行結果が下記です。
"さるとり"
もちろん上述したようなブロック形式での記述も可能です。
str = "さるとりいぬ" str.match(/.+とり/) { |result| p result[0] }
実行結果が下記です。
"さるとり"
指定した文字列が含まれない
指定した文字列が含まれない場合には、結果として「nil」が返却されることになります。
str = "さるとりいぬ" result = str.match(/.+さかな/) if result p result[0] else p "指定した文字列は含まれません。" end
実行結果は下記です。
"指定した文字列は含まれません。"
サンプルのようにチェックをせずにコンソール出力しようとすると下記のようなエラーとなります。
str = "さるとりいぬ" result = str.match(/.+さかな/) p result[0]
実行結果が下記です。
undefined method `[]' for nil:NilClass (NoMethodError)
ここまでのサンプルで確認出来るように、マッチしたデータはMachDataオブジェクトの[0]で取得することが出来ますが、「nil」の場合にはエラーとなるため注意が必要です。
日付の文字列チェック
日付の形式が「YYYY-MM-DD」形式で設定されているかを確認するような場合、下記のように記述することが可能です。
str = "2021-01-23" result = str.match(/(\A\d{4})-(\d{2})-(\d{2}\z)/) if result p result[0] p result[1] p result[2] p result[3] else p "YYYY-MM-DD形式ではありません。" end
(\A\d{4})のように()で指定した部分は[1][2][3]という形で個別に文字列を取得することも可能です。
下記サンプルのように指定した日付形式と異なる場合には「nil」が返却されることになります。
str = "20210123" result = str.match(/(\A\d{4})-(\d{2})-(\d{2}\z)/) if result p result[0] p result[1] p result[2] p result[3] else p "YYYY-MM-DD形式ではありません。" end
実行結果が下記です。
"YYYY-MM-DD形式ではありません。"
「/(\A\d{4})-(\d{2})-(\d{2}\z)/」を簡単に説明しておくと、「\A」は文字列の始まりを意味し「\d{4}」で10進数の数字4桁が続くと指定しています。
次に「-」が設定されることを意味しており、数字2桁のあとに「-」同じく数字2桁が設定され最後の「\z」が文字列の末尾を意味します。
つまり「数字4桁-数字2桁-数字2桁(YYYY-MM-DD)」形式を指定しているということになります。
matchメソッドで一致した文字列の前後を取得する
matchメソッドで一致した文字列を取得する方法についてご紹介してきましたが、一致した文字列より前だけ・後ろだけを取得出来るメソッドも用意されています。
一致した文字列の前方部分を取得
一致した文字列の前方部分を取得するには「pre_match」メソッドを利用することが出来ます。
str = "さるとりいぬさかな" result = str.match(/いぬ/) p result[0] p result.pre_match
実行結果が下記となります。
"いぬ" "さるとり"
一致した文字列の後方部分を取得
一致した文字列の後方部分を取得したい場合「post_match」メソッドを利用することが出来ます。
str = "さるとりいぬさかな" result = str.match(/いぬ/) p result[0] p result.post_match
実行結果が下記です。
"いぬ" "さかな"
さいごに: Rubyのmatchメソッドを活用して指定の文字列を取得してみよう
本記事では、Rubyのmatchメソッドを利用して正規表現による指定文字列の抽出方法をご紹介してきました。
matchメソッドの使い方自体は簡単ですので、正規表現をきちんと利用出来るかがポイントとなります。
全ての抽出パターンを覚えることは難しいため、必要に応じて検索しながら使いこなせるように利用していきましょう。
「.+」の記述で、改行を除く全ての文字列が1つ以上含まれる指定となります。