3

I'm using the following code to extract the version number from a string. The version number is the first match made only by digits and dots. For example in the string: "GT-I9000M-user 2.25.31 FROYO UGKC1 release-keys" the match would be: "2.25.31" Another example in string: "1.24.661.1hbootpreupdate:13DelCache: 1" the match would be: "1.24.661.1".

My current code is:

if (preg_match('/[\d]+[\.][\d]+/', $version, $matches)) { 
    return $matches[0]; //returning the first match 
}

This code fits only some of the cases but not all of them. For example in the first example it will only return: "2.25" instead of "2.25.31". In the second example it will return "1.24" instead of "1.24.661.1".

I'm new to RegEx so I'm having a hard time figuring it out.

Thanks for your help.

Ran
  • 391
  • 1
  • 4
  • 10
  • Jsut a tip: you need not `[]` here, because you use only 1 symbol in it. Besides, You need not to escape `.` by `\`` in `[]` You regexp is eqiualent to \d+\.\d+ – RiaD Aug 29 '11 at 19:13
  • @RiaD I thought the dot needed escaping because it can replace any single character. Is that not the case when you use it inside a class? – Ran Aug 29 '11 at 19:25
  • No reasons to use symbols `all characters` inside a class because class will be `all characters` anyway. so `print preg_match('~.~','x'); print preg_match('~[.]~','x');` prints 10 – RiaD Aug 29 '11 at 19:34

3 Answers3

11
if (preg_match('/\d+(?:\.\d+)+/', $version, $matches)) { 
    return $matches[0]; //returning the first match 
}

Allow the .x to repeat and it should work.

dee-see
  • 23,668
  • 5
  • 58
  • 91
  • why did you add the '?:' part? What does it mean in this context? – Ran Aug 29 '11 at 19:21
  • it makes the sub-pattern non capturing (it won't be returned in $matches) – Arnaud Le Blanc Aug 29 '11 at 19:23
  • @arnaud576875 I'm not sure what you mean by that. In $matches[0] I get exactly the same thing like when I use '/\d+(\.\d+)+/' ... – Ran Aug 29 '11 at 19:27
  • @Ran Without the `?:`, `$matches[1]` would contain the part inside the parentheses. It's called a capture group. Since you don't need that information, the `?:` makes it a non-capturing group. – dee-see Aug 29 '11 at 19:33
  • It does not match version numbers without dots. (in case someone need that) – sieppl Jun 22 '12 at 08:42
  • `$matches[0]` always contains the entire string that matched the entire regex. `$matches[1]` would contain the string that matched the first capturing group sub-pattern. In the answer above there is no capturing group sub-pattern. As a result `$matches[1]` would be null, or more likely out of range. – HairOfTheDog Mar 20 '13 at 05:07
2

Try this one:

'/\d+(\.\d+)+/'

The difference with yours is that it allows the .\d+ part to repeat, thus allowing multiple dots.

gic186
  • 786
  • 6
  • 18
Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
0

To match software version numbers with one/without/multiple dots one could use:

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

(kudos to authors before this post)

sieppl
  • 714
  • 5
  • 11