Percent literals: %r
Earlier this week we looked at the %w percent literal for creating arrays of strings. Another useful percent literal is %r, which creates regular expressions without needing to escape forward slashes. It may not sound like a big deal, but when you consider how often we end up writing regular expressions for URLs, it starts to make sense:
http_protocol_regex = %r{^https?://[^\s]+}
"http://example.com".match?(http_protocol_regex)
# => true
"https://example.com".match?(http_protocol_regex)
# => true
"ftp://example.com".match?(http_protocol_regex)
# => false
const httpProtocolRegex = /^https?:\/\/[^\s]+/;
"http://example.com".match(httpProtocolRegex);
// => ["http://example.com"]
"https://example.com".match(httpProtocolRegex);
// => ["https://example.com"]
"ftp://example.com".match(httpProtocolRegex);
// => null
This percent literal also pairs well with the x regex modifier, which allows you to write more readable regular expressions by ignoring whitespace and comments:
restful_url_regex = %r{
^https?:// # Match the protocol
[^/]+ # Match the domain
/ # Match the resource path
(?<resource>\w+) # Resource name capture group
(?:/(?<id>\d+))? # Resource ID capture group (optional)
$ # End of string
}x
"http://example.com/users/123".match(restful_url_regex)
# => #<MatchData "http://example.com/users/123" resource:"users" id:"123">
"https://example.com/posts".match(restful_url_regex)
# => #<MatchData "https://example.com/posts" resource:"posts" id:nil>
"ftp://example.com/files".match(restful_url_regex)
# => nil
const restfulUrlRegex =
/^https?:\/\/[^/]+\/(?<resource>\w+)(?:\/(?<id>\d+))?$/;
"http://example.com/users/123".match(restfulUrlRegex);
// => ["http://example.com/users/123", "users", "123"]
"https://example.com/posts".match(restfulUrlRegex);
// => ["https://example.com/posts", "posts", undefined]
"ftp://example.com/files".match(restfulUrlRegex);
// => null
Tidy!
History
Perl is the language that inspired Ruby's percent-based regexp literal. In Perl, you can use qr followed by a delimiter of your choice to create a regular expression. Perl also invented the x modifier for free-spacing regexes.
It seems likely that Ruby had this support from its inception, but I was only able to verify that the functionality existed in 1.4, released in 1999.