2

Ruby 3.1 adds MatchData#match and MatchData#match_length

 2 years ago
source link: https://blog.saeloun.com/2021/11/24/ruby-adds-matchdata-match-and-match-length
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Ruby 3.1 adds MatchData#match and MatchData#match_length

Nov 24, 2021 , by Alkesh Ghorpade 1 minute read

When working with strings, we come across cases where we need to match string characters or words using regular expressions. We use regular expressions widely for matching email and phone numbers formats.

A regex for a valid email address is as below -

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i

result = VALID_EMAIL_REGEX.match("[email protected]")
=> #<MatchData "[email protected]" 1:nil>

result = VALID_EMAIL_REGEX.match("invalid_email")
=> nil

Before

Ruby returns an object of class MatchData where we can use the [] function on the result object. The [] function will expect either an index or symbol as an argument. We can also access multiple matches by passing a range of indexes to the MatchData#[] method.

Let’s take an example to understand the integer, range, and symbol cases.

result = /\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$1.95")
=> #<MatchData "$1.95" dollars:"1" cents:"95">

result[0]
=> "$1.95"

result[0..2]
=> ["$1.95", "1", "95"]

result[3]
=> nil

result[:dollars]
=> "1"

result[:cents]
=> "95"

result[:cents].length
=> 2

To access the length, we had to chain .length on [] method of MatchData class.

After

With the recent change in Ruby 3.1, we have two methods to access the match data and its length. Both MatchData#match and MatchData#match_length accept either an index or a symbol as an argument.

So the above example will change as below:

result = /\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$1.95")
=> #<MatchData "$1.95" dollars:"1" cents:"95">

result.match(0)
=> "$1.95"

result.match(1)
=> "1"

result.match(:dollars)
=> "1"

result.match(:cents)
=> "95"

result.match_length(:cents)
=> 2

Note:

MatchData#match is not same as MatchData[]. MatchData[] accepts an integer, range, or symbol as an argument, but #match allows only a single index or symbol. Passing a range to match method will raise an error as below:

result.match(0..2)
(irb):44:in `match': no implicit conversion of Range into Integer (TypeError)

For more discussion related to this change, please refer to this PR.


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK