This blog is part of our Ruby 3.1 series.
Ruby 3.1 introduces the MatchData#match & MatchData#match_length methods which returns the substring matched against a regular expression & it's length respectively.
1=> str = "Ruby 3.1 introduces MatchData#match method" 2=> m = /(?<lang>\S+)(\s)(?<version>[\d\.]+)/.match(str) 3=> #<MatchData "Ruby 3.1" lang:"Ruby" version:"3.1">
Before Ruby 3.1
We have MatchData#[] method to access all the substring groups which are matched. We can access either a single match or multiple matches by giving a single index or range of indexes respectively using MatchData#[] method.
1=> m[:lang] 2=> "Ruby" 3 4=> m[1] 5=> "Ruby" 6=> m[:version] 7=> "3.1" 8 9=> m[0..2] 10=> ["Ruby 3.1", "Ruby", "3.1"] 11 12=> m[1..2] 13=> ["Ruby", "3.1"] 14 15 16=> m[0].length 17=> 8
After Ruby 3.1
We have two new methods now to access the match data & it's length. The MatchData#match & MatchData#match_length methods accepts either an index or a symbol as an argument to return the match data & it's length.
1=> m.match(0) 2=> "Ruby 3.1" 3 4=> m.match(:version) 5=> "3.1" 6 7=> m.match(3) 8=> nil 9 10=> m.match_length(0) 11=> 8 12 13=> m.match_length(:version) 14=> 3 15 16=> m.match_length(3) 17=> nil
Please note that MatchData#match is not same as MatchData#[] method. The later accepts an optional length or range as an argument to return the matched data but the former doesn't accept it, instead it allows only a single index or symbol as argument.
Here's the relevant pull request and feature discussion for this change.