[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]