3

I need to verify if the version number of application bigger than 1.18.10. How regular expression should look like in this case?

Alex L
  • 8,748
  • 5
  • 49
  • 75
ykiveish
  • 69
  • 6
  • 8
    Are you sure regex is the best way to go about this? – Preet Kukreti Jun 11 '13 at 08:59
  • to understand why you don't want to use a RE, you should read courses on [automata](http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-045j-automata-computability-and-complexity-spring-2011/lecture-notes/MIT6_045JS11_lec03.pdf) and [Regular Expressions/NFA](http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-045j-automata-computability-and-complexity-spring-2011/lecture-notes/MIT6_045JS11_lec04.pdf) to understand what RE really are. – zmo Jun 11 '13 at 09:36

4 Answers4

15

Don't use regular expressions for this. Use split and tuple comparison:

def is_recent(version):
    version_as_ints = (int(x) for x in version.split('.'))
    return tuple(version_as_ints) > (1, 18, 10)

And then check is_recent("1.10.11") or is_recent("1.18.12")

Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82
4

Seems like this battery has already been included in Python in distutils.version :

from distutils.version import LooseVersion
LooseVersion("1.18.11") > LooseVersion("1.18.10")
#True

LooseVersion("1.2.11") > LooseVersion("1.18.10")
#False (note that "2">"18" is True)

LooseVersion("1.18.10a") > LooseVersion("1.18.10")
#True

This takes into account splitting and comparing both version number parts as integers, and non-numeric parts (e.g alphabetic extension) seperately and correctly. (If you want the alternate behaviour, (lexicographical comparison), you can directly compare the tuples of strings that result on a version_num.split("."))

Note that there is also a StrictVersion variant that will throw an exception (ValueError) on alphabetic characters in the version string. See also PEP386 which is planning to deprecate both, replacing them with a NormalizedVersion.

Preet Kukreti
  • 8,417
  • 28
  • 36
0

Don't use regular expression for that, but something like:

major, minor, patch = v.split('.')
if int(major) > 1 or (int(major) == 1 and int(minor) >= 18):
    ...
Guillaume
  • 10,463
  • 1
  • 33
  • 47
0

Not sure exactly why you need a regex, it's not a particularly good tool for doing complex range checking.

I would just split the string into a three-element array and then check each element, something like:

(p1, p2, p3) = verstr.split(".")

# May want to check they're numeric first.

if int(p1) < 1: return False
if int(p1) == 1:
    if int(p2) < 18: return False
    if int(p2) == 18:
        if int(p3) < 10: return False
return True
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953