Reputation: 1995
I am trying to return the version of Ruby (such as 2.1.0) from a regular expression. Here's the string as it should be evaluated by a regular expression:
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin12.0]\n
How would I go about extracting 2.1.0
from this? It seems to me that the best way to do this would be to extract the numbers around two periods, but no spaces or characters around them. So basically, it would pull just 2.1.0
instead of anything else.
Any ideas?
Upvotes: 0
Views: 297
Reputation: 48649
Try this:
str = "ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin12.0]\n"
pieces = str.split(" ", 3)
version, patch_num = pieces[1].split('p')
puts version
--output:--
2.1.0
Upvotes: 0
Reputation: 84423
Rather than parsing the output of whatever you're trying to parse, just inspect the RUBY_VERSION constant. On any recent Ruby, you should get output similar to the following in a REPL like irb or pry:
RUBY_VERSION
# => "2.1.0"
Or ask Ruby on the command line with:
$ ruby -e 'puts RUBY_VERSION'
2.1.0
Upvotes: 1
Reputation: 110725
Edit: I misread the question. I assumed the given string might be embedded in other text, but on re-reading I see that evidently is not the case. The regex given by @theTinMan is sufficient and preferred.tidE
This is one way:
str = "ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin12.0]\n"
str[/[Rr]uby\s+(\d\.\d\.\d)/,1]
#=> "2.1.0"
This could instead be written:
str[/[Rr]uby\s+(\d(\.\d){2})/,1]
If matching "Ruby 2.1" or Ruby "2" were desired, one could use
str[/[Rr]uby\s+(\d(\.\d){,2})/,1] # match "2", "2.1" or "2.1.1"
or
str[/[Rr]uby\s+(\d(\.\d){1,2})/,1] # "2.1" or "2.1.1", but not "2"
Upvotes: 1
Reputation: 160601
How about:
str = "ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin12.0]\n"
str[/[\d.]+/] # => "2.1.0"
[\d.]+
means "find a string of characters that are digits or '.'
.
str[/[\d.]+/]
will find the first such string that matches and return it. See String#[]
for more information.
The question is, do all versions and Ruby interpreters return their version information consistently? If your code could end up running on something besides the stock Ruby you might have a problem if the -v
output changes in a way that puts the version farther into the string and something else matches first.
TinMan, I think you need a more rigorous regex; e.g., "1..0"[/[\d.]+/] => "1..0", "2.0.0.1."[/[\d.]+/] => "2.0.0.1.", "2.0.0.0.1"[/[\d.]+/] => "2.0.0.0.1"
Ruby uses a similar style to Semantic Versioning, so the actual format of the string shouldn't vary, allowing a simple pattern. Where the version number occurs might not be defined though.
IF it went crazy, something like /[\d.]{3,5}/
should herd things back into some semblance of order, and normalize the returned value:
[
'foo 1.0 bar',
'foo 1.1.1 bar',
'foo 1.1.1.1 bar'
].map{ |s| s[/[\d.]{3,5}/] }
# => ["1.0", "1.1.1", "1.1.1"]
If you're trying to do this with running code, why not use the predefined constant RUBY_VERSION
:
RUBY_VERSION # => "2.1.2"
Version numbers are notoriously difficult to grab, because there are so many different ways that people use to format them. Over the last several years we've seen some attempts to create some order and commonality.
Upvotes: 4