This blog is part of our Ruby 2.4 series.

Ruby has MatchData type which is returned by Regexp#match and Regexp.last_match.

It has methods #names and #captures to return the names used for capturing and the actual captured data respectively.

pattern = /(?<number>\d+) (?<word>\w+)/
match_data = pattern.match('100 thousand')
#=> #<MatchData "100 thousand" number:"100" word:"thousand">

>> match_data.names
=> ["number", "word"]
>> match_data.captures
=> ["100", "thousand"]

If we want all named captures in a key value pair, we have to combine the result of names and captures.

match_data.names.zip(match_data.captures).to_h
#=> {"number"=>"100", "word"=>"thousand"}

Ruby 2.4 adds #named_captures which returns both the name and data of the capture groups.

pattern=/(?<number>\d+) (?<word>\w+)/
match_data = pattern.match('100 thousand')

match_data.named_captures
#=> {"number"=>"100", "word"=>"thousand"}