📑

【Ruby 3.4 Advent Calender】MatchData#bytebegin / byteend が追加された【10日目】

2024/12/10に公開

Ruby 3.4 Advent Calender 10日目の記事です。

これはなに

今年 2024年12月25日にリリースされる予定の Ruby 3.4 の新機能や変更点などを1つずつ紹介していく Advent Calender になります。
基本的には NEWS に載っている機能を紹介すると思うんですがここにない機能についても書くかもしれません。
また、記事を書いてる時点ではまだ Ruby 3.4 はリリースされる前なので Ruby 3.4 がリリースされた時点で機能が変わっている 可能性があるかもしれないので注意してください。
記事のまとめは ここを参照 してください。

MatchData#bytebegin / byteend が追加された

Ruby 3.4 で MatchData#bytebegin / byteend メソッドがそれぞれ追加されました。
これはバイト単位でマッチした位置情報を返すメソッドになります。

result = /(\d+)年(\d+)月/.match("2021年1月")

pp result
# => #<MatchData "2021年1月" 1:"2021" 2:"1">

# マッチした位置をバイト単位で返す
# 引数はそれぞれ () でキャプチャしている場所になる
# (\d+)年 の部分
pp result.bytebegin(1)   # => 0
pp result.byteend(1)     # => 4

# (\d+)月 の部分
pp result.bytebegin(2)   # => 7
pp result.byteend(2)     # => 8

既存でも MatchData#begin / end は存在するんですがこちらは文字単位の位置情報を返します。

result = /(\d+)年(\d+)月/.match("2021年1月")

pp result
# => #<MatchData "2021年1月" 1:"2021" 2:"1">

# 『月』でマッチした位置は以下のような文字の位置を返す
pp result.begin(2)   # => 5
pp result.end(2)     # => 6

Ruby 3.3 時点でもバイト単位ので位置情報は MatchData#byteoffset で取得できるんですが、先頭と終端をそれぞれ別々に取得する場合には個別のメソッドで定義されている方がパフォーマンスの改善にもつながるので MatchData#bytebegin / byteend がそれぞれ追加されました。

result = /(\d+)年(\d+)月/.match("2021年1月")

# Ruby 3.3 でもこのようにして先頭/終端を取得できる
pp result.byteoffset(2)
# => [7, 8]

関連

GitHubで編集を提案

Discussion