LoginSignup
0
0

More than 3 years have passed since last update.

Ruby手習い(MatchDataクラス)

Posted at

[https://blog.jnito.com/entry/2019/05/03/121235:title]

上記記事の値札分割問題。

自分で書いたコード

def split_price(price_text)
  match = price_text&.match(/[\d\s0-9.,-]+|価格未定/)
  num = match ? match[0] : ""
  unit = price_text ? price_text[num.length..-1] : ""
  [num, unit]
end

数値部分だけみつけて、全体から数値部分をとりだした。

他の回答例

def split_price(price_text)
  regex = /([^万円]+)(万?円)/
  regex.match(price_text).to_a[1..2] || [price_text.to_s, '']
end

「数値部分だけとりだし、全体から数値部分を削除して単位部分を得る」ではなく、正規表現の中で()により数字部分と単位部分をまとめて取得するのがきれいだ。

def split_price(price_text)
  price_text.to_s.match(/([^万円]*)(.*)/)[1..2]
end

なるほど!*をつかうことによって必ずマッチする(少なくとも""がマッチする)ため、matchの戻り値がnilの場合を別に定めなくてすむ。

学んだこと

  • String#match(regexp)Regexp#match(string)の戻り値はMatchDataクラス。
  • MatchData[n]はn=0で$&(マッチした最初のの文字列全体)を返し、n>=1で${n}(マッチした最初の文字列のうち、正規表現内の()により得られたn番目の部分文字列)を返す。
    • マッチしなければnilを返す。
  • MatchData#to_a[$&, $1, $2, $3...]を返す。

参考:[https://docs.ruby-lang.org/ja/latest/class/MatchData.html#I_--5B--5D:title]

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