Ruby Regex not matching what it should be [duplicate] - ruby

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

Related

Regex with Ruby gsub [duplicate]

This question already has answers here:
Reference - What does this regex mean?
(1 answer)
How to back reference "inner" selections ( () ) in a regular expression?
(3 answers)
Closed 4 years ago.
My goal is to replace spaces and "/" with '-' from the input:
name = "chard / pinot noir"
to get:
"chard-pinot-noir"
My first attempt is:
name.gsub(/ \/\ /, '-') #=> "chart-pinot noir"
My second attempt is:
name.gsub(/\/\s+/, '-') #=> "chard -pinot noir"
My third attempt is:
name.gsub(/\s+/, '-') #=> "chard-/-pinot-noir"
This article helped. The first group checks for a forward slash /, and contains a break. The second portion replaces a forward slash with '-'. However, the space remains. I believe /s matches spaces, but I can't get it to work while simultaneously checking for forward slash.
My question is how can I get the desired result, shown above, with varying strings using either regex or a ruby helpers. Is there a preferred way? Pro / Con ?
If you don't know much about regex, you can do this way.
name = "chard / pinot noir"
(name.split() - ["/"]).join("-")
=> "chard-pinot-noir"
I think the best way is use with regex as #Sagar Pandya described above.
name.gsub(/[\/\s]+/,'-')
=> "chard-pinot-noir"

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)\"/)

Understanding Ruby match method of Regexp class [duplicate]

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.

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];

Help with Regex statement in Ruby

I have a string called 'raw'. I am trying to parse it in ruby in the following way:
raw = "HbA1C ranging 8.0—10.0%"
raw.scan /\d*\.?\d+[ ]*(-+|\342\200\224)[ ]*\d*\.?\d+/
The output from the above is []. I think it should be: ["8.0—10.0"].
Does anyone have any insight into what is wrong with the above regex statement?
Note: \342\200\224 is equal to — (em-dash, U+2014).
The piece that is not working is:
(-+|\342\200\224)
I think it should be equivalent to saying, match on 1 or more - OR match on the string \342\200\224.
Any help would be greatly appreciated it!
The original regex works for me (ruby 1.8.7), justs needs the capture to be non-capturing and scan will output the entire match. Or switch to String#[] or String#match instead of String#scan and don't edit the regex.
raw = "HbA1C ranging 8.0—10.0%"
raw.scan /\d*\.?\d+[ ]*(?:-+|\342\200\224)[ ]*\d*\.?\d+/
# => ["8.0—10.0"]
For testing/building regular expressions in Ruby there's a fantastic tool over at http://rubular.com that makes it a lot easier. http://rubular.com/r/b1318BBimb is the edited regex with a few test cases to make sure it works against them.
raw = "HbA1C ranging 8.0—10.0%"
raw.scan(/\d+\.\d+.+\d+\.\d+/)
#=> ["8.0\342\200\22410.0"]

Resources