Understanding Ruby match method of Regexp class [duplicate] - ruby

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 6 years ago.
I was reading about the match method in ruby, I understood most of the example given at Regexp
But I am failing to understand, why is:
/[0-9a-f]/.match('9f')
=> #<MatchData "9">
And not:
=> #<MatchData "9f">
I might be missing some basic understanding of Regex, so bear with me.

Because you're asking it to match a single character of class 0-9 or a-f.
If you want to match multiple use a plus or an asterisk after the character classes e.g. /[0-9a-f]+/.match('9f')
It's all here.

Related

Ruby: how to perform lazy regex matching? [duplicate]

This question already has answers here:
Capturing groups don't work as expected with Ruby scan method
(3 answers)
Closed 5 years ago.
This is a following up question regarding Lazy (ungreedy) matching multiple groups using regex. I try to use the method but not very successful.
I grab a string from gitlab API and try to extract all the repos. The name of repo follows the format of "https://gitlab.example.com/foo/xxx.git".
So far, if I try this, it works OK.
gitlab_str.scan(/\"https\:\/\/gitlab\.example\.com\/foo\//)
But to add name wildcard is tricky, I use the method from the previous question:
gitlab_str.scan(/\"https\:\/\/gitlab\.example\.com\/foo\/(.*?)\.git\"/)
It says to use (.*?) for lazy matching, but it doesn't seem to work.
Thanks a lot for the help.
If we have the following string:
gitlab_str = "\"https://gitlab.example.com/foo/xxx.git\""
The following RegEx will return [["xxx"]], which is expected:
gitlab_str.scan(/\"https\:\/\/gitlab\.example\.com\/foo\/(.*?)\.git\"/)
Because you had the (.*?). Note the parenthesis, so only what's inside the parenthesis will be returned.
If you want to return the whole string matched, you can just remove the parenthesis:
gitlab_str.scan(/\"https\:\/\/gitlab\.example\.com\/foo\/.*?\.git\"/)
This will return:
["\"https://gitlab.example.com/foo/xxx.git\""]
It also works for multiple occurrences:
> gitlab_str = "\"https://gitlab.example.com/foo/xxx.git\" and \"https://gitlab.example.com/foo/yyy.git\""
> gitlab_str.scan(/\"https\:\/\/gitlab\.example\.com\/foo\/.*?\.git\"/)
=> ["\"https://gitlab.example.com/foo/xxx.git\"", "\"https://gitlab.example.com/foo/yyy.git\""]
Finally, if you want to remove the https:// part from the resulting matches, then just wrap everything but that part with () in the RegEx:
gitlab_str.scan(/\"https\:\/\/(gitlab\.example\.com\/foo\/.*?\.git)\"/)

Surprising string concatenation [duplicate]

This question already has answers here:
Where is Ruby's string literal juxtaposition feature officially documented?
(4 answers)
Closed 7 years ago.
I am surprised by some string concatenation I've stumbled upon in a codebase I support. Why, or how really, does the following manage to concatenate two strings together?
queue_name = 'gen-request-' "#{ENV['USERNAME'].gsub('.','')}"
=> "gen-request-robertkuhar"
I had expected to see a '+' between the two strings, but its not there. Is it implied or something?
I know this just makes more sense with up-the-middle string interpolation. Thats not what I'm asking. I want to know what it is about the language syntax that allows this to work in the first place.
This only works for string literals, and a part of the literal syntax.
If you have 2 string literals with just whitespace between them, they get turned into a single string. It's a convention borrowed from later versions of C.

Ruby Regex not matching what it should be [duplicate]

This question already has answers here:
How to match all occurrences of a regular expression in Ruby
(6 answers)
Closed 8 years ago.
I've got the following regex:
regex = /\$([a-zA-Z.]+)/
and the following query
query = "Show me the PE Ratio for $AAPL, $TSLA"
Now regex.match(query) should capture AAPL and TSLA, but instead I get the following:
#<MatchData "$AAPL" 1:"AAPL">
which is completely wrong. Anyone know why?
Note that this regex works fine on Rubular: http://rubular.com/r/j0maQHnVFF
In Ruby the .match method will only return the first capture. You need it to return all captured matches, like the /g flag in PCRE
You can use the scan method. The scan method will either give you an array of all the matches or, if you pass it a block, pass each match to the block.
Code
query.scan(/\$([a-zA-Z.]+)/)
Fixed it, needed to use .scan instead of .match

Ruby << for String [duplicate]

This question already has answers here:
What are <-- Ruby Strings called? And how do I insert variables in them?
(3 answers)
Closed 8 years ago.
Can someone tell me the name of
<<-MAP
STRING HERE
MAP
operator (<<-) in ruby? I tried search for 'double less than' but it didn't turn up anything. I want to learn more about it but don't even know what it's called!
Thanks
Thats called the here doc syntax .Generally used to enter multiline strings. You can read about it here http://blog.jayfields.com/2006/12/ruby-multiline-strings-here-doc-or.html
and also here The <<- operator on Ruby, where is it documented?
It's not an operator, it's a here document (aka heredoc) String literal. It works more or less like heredocs in other languages.
It is specified in section 8.7.6.3.6 of the ISO Ruby Language Specification.

How can one write this gsub regex match? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Perfect way to write a gsub for a regex match?
I am trying to write a gsub for a regex match, but I imagine there's a more perfect way to do this .
My equation :
ref.gsub(ref.match(/settings(.*)/)[1], '')
So that I can take this settings/animals, and return just settings.
But what if settings is null? Than my [1] fails as expected.
So how can one write the above statement assuming that sometimes settings won't match ?
Use /(settings|)(.*)/, then first group will return you "settings" or empty string, if it is not present.
puts 'settings/123'.match(/(settings|)(.*)/)[1];
puts 'Xettings/123'.match(/(settings|)(.*)/)[1];

Resources