Bilow Yuriy
Bilow Yuriy

Reputation: 1319

Getting version number with regex

I have a string like:

"MyProgramm build version 0.0.7.161"

I want to get the version from it. I tried:

String(build_num[/MyProgramm build version (\d*.\d*.\d*.\d*)$/, 1])

and I get:

", 0.0.7.161"

Why do I get the comma at the front?

Upvotes: 2

Views: 1079

Answers (2)

the Tin Man
the Tin Man

Reputation: 160601

You can do something simple like:

str = "MyProgramm build version 0.0.7.161"
str.scan(/\d+/).join('.') # => "0.0.7.161"

That's fine if you know the only numbers in the string are in the version substring. But, what happens if the name of the app has a number in it?

str = "HTML2PDF build version 0.0.7.161"
str.scan(/\d+/).join('.') # => "2.0.0.7.161"

or worse:

str = "foobar_v1.0 build version 1.0.7.161"
str.scan(/\d+/).join('.') # => "1.0.1.0.7.161"

Obviously that's not what you want, so, at that point the code has to get smarter. If the version substring is always at the end of the string, then something like this will work:

str = "HTML2PDF build version 0.0.7.161"
str.split.last.scan(/\d+/).join('.') # => "0.0.7.161"

But, now that you have the substring, what are you going to do with it? Compare it to something? You can't compare this sort of string to get an idea of one version being less than another:

"0.0.7.161" < "0.0.7.2" # => true

Comparing characters isn't the same as comparing integers so there needs to be more intelligence, or at least something to make sure the strings are going to sort/compare in the desired order:

str.split.last.scan(/\d+/).map{ |s| '%03d' % s.to_i }.join('.') # => "000.000.007.161"
"000.000.007.161" < "000.000.007.002" # => false

Or conversely:

"000.000.007.002" < "000.000.007.161" # => true

Version number comparison is a problem, and you'll find various ways people have tried to deal with it out there. The couple of times I've needed to do it I fall back on using the code in Ruby's Gem::Version class, which helps. Still, you'll run into weirdness now and then and have to figure out what works for your situation.

Upvotes: 7

Anthony
Anthony

Reputation: 15967

I'm able to do this using the scan method like so:

[20] pry(main)> string
=> "MyProgramm build version 0.0.7.161"
[21] pry(main)> string.scan(/\d\.*/).join
=> "0.0.7.161"

so try

state.scan(/\d\.*/).join

Upvotes: 0

Related Questions