Ruby 3.2 アドベントカレンダーの13日目の記事です。
MatchData
MatchData#byteoffset
Feature #13110: Byte-based operations for String - Ruby master - Ruby Issue Tracking System
MatchData は正規表現に適合した文字列を表すクラス。
MatchData#offset
で適合した全体や括弧の部分の範囲を文字単位で取得できる。
s = "あいう123えおabcかきく" m = s.match(/(\w+)\W*(\w+)/) #=> #<MatchData "123えおabc" 1:"123" 2:"abc"> m.offset(0) #=> [3, 11] 正規表現全体に適合したのは s[3...11] m.offset(1) #=> [3, 6] 最初の括弧に適合した '123' は s[3...6] m.offset(2) #=> [8, 11] 次の括弧に適合した 'abc' は s[8...11]
Ruby 3.2 でこれをバイト単位で取り出せるようにした MatchData#byteoffset
が追加された。
m.byteoffset(0) #=> [9, 21] 正規表現全体に適合したのは s.b[9...21] m.byteoffset(1) #=> [9, 12] 最初の括弧に適合した '123' は s.b[9...12] m.byteoffset(2) #=> [18, 21] 次の括弧に適合した 'abc' は s.b[18...21]
MatchData#deconstruct / MatchData#deconstruct_keys
Ruby 3.2 で MatchData#deconstruct
と MatchData#deconstruct_keys
が追加された。
MatchData#deconstruct
は MatchData#captures
のエイリアス。
s = "あいう123えおabcかきく" m = s.match(/(\w+)\W*(\w+)/) #=> #<MatchData "123えおabc" 1:"123" 2:"abc"> m.deconstruct #=> ["123", "abc"]
正規表現内の括弧には名前をつけることができて MatchData#[]
や MatchData#named_captures
で参照できる。
m = s.match(/(?<a>\w+)\W*(?<b>\w+)/) #=> #<MatchData "123えおabc" a:"123" b:"abc"> m['a'] #=> "123" m['b'] #=> "abc" m.named_captures #=> {"a"=>"123", "b"=>"abc"}
MatchData#deconstruct_keys
はシンボルで名前を指定して参照できる。nil
を指定するとすべての名前付き括弧が参照できる。
m.deconstruct_keys(nil) #=> {:a=>"123", :b=>"abc"} m.deconstruct_keys([:b]) #=> {:b=>"abc"}
deconstruct
や deconstruct_keys
という名前でピンときた人もいると思うけど、これによって MatchData をパターンマッチで使えるようになるということらしい。
IP_REGEX = / (?<first_octet>\d{1,3})\. (?<second_octet>\d{1,3})\. (?<third_octet>\d{1,3})\. (?<fourth_octet>\d{1,3}) /x '192.168.1.1'.match(IP_REGEX) in {first_octet: '192', fourth_octet: '1'} #=> true
自分はピンとこなかった。パターンマッチよくわからん。