Ruby学習 「プロを目指す人のためのRuby入門」 6章

はじめに

プロを目指す人のためのRuby入門Rubyを学習しています。
重要そうな部分や理解が難しかった部分、忘れそうなことについて学習メモを書きます。
今回は第6章「正規表現を理解する」について書いていきます。

記事中のプログラムはirbで動作を確認しました。

Rubyにおける正規表現オブジェクト

  • 正規表現オブジェクトは「/正規表現/」のようにスラッシュで正規表現パターンを囲んで作成
  • 正規表現Regexpクラスのオブジェクト
  • 正規表現と文字列を比較する場合は=~がよく使用される
  • =~でマッチした場合は文字列のマッチした位置、マッチしなかった場合はnilが返る
'111-2222' =~ /\d{3}-\d{4}/
=> 0
'a111-2222' =~ /\d{3}-\d{4}/
=> 1
'a111-22' =~ /\d{3}-\d{4}/
=> nil
  • !~でアンマッチの時にtrue、マッチしたときにfalseを返す
  • ()を使って抜き出したい部分を指定する機能をキャプチャという
text = '今日は2020年3月29日です。'
=> "今日は2020年3月29日です。"
m = /(\d+)年(\d+)月(\d+)日/.match(text)
=> #<MatchData "2020年3月29日" 1:"2020" 2:"3" 3:"29">
m[1]
=> "2020"
m[2]
=> "3"
m[3]
=> "29"
m[0]
=> "2020年3月29日"
  • matchメソッドは正規表現とマッチするとMatchDataオブジェクトが返り、マッチしないとnilが返る
  • (?<キャプチャ名>)というメタ文字でキャプチャの結果に名前を付けられる
text = '今日は2020年3月29日です。'
=> "今日は2020年3月29日です。"
m = /(?<year>\d+)年(?<month>\d+)月(?<day>\d+)日/.match(text)
=> #<MatchData "2020年3月29日" year:"2020" month:"3" day:"29">
m[:year]
=> "2020"
m[:month]
=> "3"
m[:day]
=> "29"
m['year']
=> "2020"
  • 左辺に正規表現リテラル、右辺に文字列を置いて=~演算子を使うとキャプチャの名前がローカル変数に割り当てられる
  • 上記は左辺と右辺を入れ替えたり、正規表現オブジェクトを変数に入れたりすると使えない

  • scanメソッドは引数で渡した正規表現にマッチした部分を配列に入れて返す

  • 文字列[正規表現]で文字列から正規表現にマッチした部分を抜き出せる
  • splitメソッドは正規表現を渡すと、マッチした文字列を区切り文字として文字列を分割し、配列で返す
  • gsubメソッドは第一引数の正規表現にマッチした文字列を打2引数の文字列で置換する

正規表現オブジェクトについてもっと詳しく

  • Regexp.new(正規表現)で正規表現オブジェクトを作成できる
  • %r(%記法)で正規表現オブジェクトを作成できる
  • 正規表現はcase文のwhen節で使うことができる
  • /正規表現/オプションの形式で正規表現オブジェクト作成時にオプションを設定できる(%記法でも可能)
  • iオプションをつけると大文字小文字を区別しない
  • mオプションをつけると任意の文字を表す.が改行文字にもマッチする
  • xオプションをつけると空白文字が無視され、#を使ったコメントを正規表現内にかける
  • Rubyには$で始まる組み込み変数があり、=~演算子やmatchメソッドを使うといくつかの組み込み変数にマッチした結果が代入されるが、MatchDataオブジェクトを利用する方が可読性や保守性の面で優れている
  • match?メソッドは正規表現にマッチするとtrue、マッチしなければfalseを返す。組み込み変数やRegexp.last_matchの内容を書き換えないため=~演算子やmatchメソッドよりも高速

感想

正規表現を扱う方法が複数あることが分かった。
可読性や処理速度を考慮し、用途に合った方法を選ぶこと意識する。

参考文献

この記事は以下の情報を参考にして執筆しました。