LoginSignup
0
0

More than 1 year has passed since last update.

チャート式ruby-appendix-V(rubular)

Last updated at Posted at 2020-11-10

!Mac OS X-10.15.7 !ruby-2.7.1p83

正規表現regular expression

文字情報を取り出す便利ツールが正規表現(regular expression)です.これって覚えようとして挫折したことないですか?私はRegExpを10年以上使えなくて,本を何冊もトライしたんですが,途中で諦めました.でもね.http://rubular.com でわずか10分でバリバリ使えるようになってました.コツは,やっぱりTDDです.

rubular

img
Rubularの画面

Rubularの画面を見てください.一番上に正規表現を入れます.左下にtest stringを入れます.そうすると右に抽出結果が出てきます.

まずはtest文字列として

line = '* fix calc kpoints:50, in_plane:0.98, vertical:1.00'

を考えます.

これから数値の配列[0.98, 1.00]を取り出します.まず,取り出す文字列(capture everything enclosed)は

(.+)

で取り出されます.any single caharacterを表す'.'と,一つ以上を表す(+)を入れています.これからいらん文字を外していくと考えてください.少し試行錯誤すれば,

: in_plane:(.+), vertical:(.+)

なんかで数値だけが取り出せたでしょうか? 

正規表現ってたくさん覚えないといけないと思いがちですが,Regex quick referenceにまとめられている要素だけでできています.大きく分類すると,

  • 範囲指定(左列上),
  • 位置指定子(左列下)
  • 文字指定子(中列)
  • 量指定子(右列)

です.さらに丸括弧()で抽出になります.あとは,そのアンチョコ(カンペ)を見ながら,試行錯誤するだけなんですね.どうです,TDDでしょ.

rubyでの利用

rubyに組み込むには,

line = "* fix calc kpoints:50, in_plane:0.98, vertical:1.00"

string = Regexp.new("\\* fix calc kpoints:50, in_plane:(.+), vertical:(.+)")
line =~ string
p [$1.to_f, $2.to_f] #=> [0.98, 1.00]

res = line.scan(string)
p res #=> [["0.98", "1.00"]]
p res[0].map(&:to_f) #=> [0.98, 1.0]

p m = line.match(string) 
#=> #<MatchData "* fix calc kpoints:50, in_plane:0.98, vertical:1.00" 1:"0.98" 2:"1.00">
p [m[1].to_f, m[2].to_f] #=> [0.98, 1.0]

などとします.それぞれにちょっとした特徴がありますが,どれを使ってもうまくいくときにはうまくいきます.

tagつきのregexp

さらにこの頃,気がついた手法で,tagをつけるのがあります.

string = Regexp.new('in_plane:(?<x>.+), vertical:(?<y>.+)')
res = line.match(string)
=> #<MatchData "in_plane:0.98, vertical:1.00" x:"0.98" y:"1.00">
irb(main): > res[:x]
=> "0.98"
irb(main): > res[:y]
=> "1.00"

:x とか :y というsymbolで取れます.

'=~' だとさらに

irb(main):001:0> line = '* fix calc kpoints:50, in_plane:0.98, vertical:1.00'
=> "* fix calc kpoints:50, in_plane:0.98, vertical:1.00"
irb(main):003:0> /in_plane:(?<x>.+), vertical:(?<y>.+)/ =~ line
=> 23
irb(main):004:0> x
=> "0.98"
irb(main):005:0> y
=> "1.00"

対応した名前がついたローカル変数(local variables with corresponding names)になります.

えっとでも,数値を取り出すときはscanf("%i, %f")も便利です.

p line.scanf("* fix calc kpoints:50, in_plane:%f, vertical:%f")
#=>[0.98, 1.0]

C言語と同じformatです.regexpで取り出すと文字列なんで,to_fとかto_iでfloat, intに変換する必要がありますが,scanfで取り出すとそのままのtypeで取り出されます.


  • source ~/git_hub/ruby_docs/chart_style_ruby/c05_rubular.org
0
0
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
0
0