Ben
Ben

Reputation: 62364

Regex unable to parse version

My objective is to get the version number from a string where the string may contain anything. Here's my example data set:

Version 1.32.0.1
Version 1.32.0.1c
Version 1.32.1
Version 1.33.2e
Version 1.32

I've attempted to match that with this regex (\d+\.\d+(?:\.\d+)?)(\w?) but I can't seem to figure out why this won't match the 4th decimal value, even with the descriptive breakdown provided by regex101.com.

What am I misunderstanding about this regex causing it to not match all version variations?

Upvotes: 1

Views: 204

Answers (3)

asdator1213
asdator1213

Reputation: 27

Try this regex, maybe it's the result you want to achieve:

\w+[.](\w*[.]?)*

In a text block:

Version 1_32.0.1
Version 1.32.0.1c
Version 1.32.1
Version 1.33.2e.
Version 1.32
Version e342

it matches only version numbers which starts with any alphanumeric characters (and underscores), followed by one dot and in the loop followed by zero or many any of alphanumeric character with dot at the end of a line.

Here is a demo: regex

Upvotes: 0

Sweeper
Sweeper

Reputation: 271070

Count how many \d+ you have got. You should count 3. So your regex will at most match 3 numbers, and it cannot possibly match 4.

I'm not sure if this is a typo or you genuinely don't understand, but this can be fixed by adding another group:

(\d+\.\d+(?:\.\d+(?:\.\d+)?)?)(\w?)

This can be shortened to:

\d+(?:\.\d+){1,3}(\w?)

If you want to match any number of numbers more than 1, you can do:

\d+(?:\.\d+)+(\w?)

\w would match _ as well. If you don't want that, you can replace it with [a-z].

Upvotes: 1

mukesh210
mukesh210

Reputation: 2892

Currently you have used ? in non-capturing group which will match only 3rd decimal value(even if you have 3rd and 4th decimal value present). One solution would be to use * instead of ? in non-capturing group for your non-capturing group to match 3rd as well as 4th decimal value.

I tried in Scala and it works perfectly for your inputs above:

  val text: String = "Version 1.32.0.1c"
  val pattern = """(\d+\.\d+(?:\.\d+)*)(\w?)""".r
  val res: Regex.MatchIterator = pattern.findAllIn(text)
  println(res.group(1)) // 1.32.0.1
  println(res.group(2)) // c

Upvotes: 1

Related Questions