Here comes a function to compare version numbers of e.g. Maven artifacts in Jython / Python.
import re
def cmpver(vA, vB):
"""
Compares two version number strings
@param vA: first version string to compare
@param vB: second version string to compare
@author Sebastian Thomschke
@return negative if vA < vB, zero if vA == vB, positive if vA > vB.
Examples:
>>> cmpver("0", "1")
-1
>>> cmpver("1", "0")
1
>>> cmpver("1", "1")
0
>>> cmpver("1.0", "1.0")
0
>>> cmpver("1.0", "1")
0
>>> cmpver("1", "1.0")
0
>>> cmpver("1.1.0", "1.0.1")
1
>>> cmpver("1.0.1", "1.1.1")
-1
>>> cmpver("0.3-SNAPSHOT", "0.3")
-1
>>> cmpver("0.3", "0.3-SNAPSHOT")
1
>>> cmpver("1.3b", "1.3c")
-1
>>> cmpver("1.14b", "1.3c")
1
"""
if vA == vB: return 0
def num(s):
if s.isdigit(): return int(s)
return s
seqA = map(num, re.findall('\d+|\w+', vA.replace('-SNAPSHOT', '')))
seqB = map(num, re.findall('\d+|\w+', vB.replace('-SNAPSHOT', '')))
# this is to ensure that 1.0 == 1.0.0 in cmp(..)
lenA, lenB = len(seqA), len(seqB)
for i in range(lenA, lenB): seqA += (0,)
for i in range(lenB, lenA): seqB += (0,)
rc = cmp(seqA, seqB)
if rc == 0:
if vA.endswith('-SNAPSHOT'): return -1
if vB.endswith('-SNAPSHOT'): return 1
return rc
Theoretically lines 43 – 49 could be written in a more compact way but using the short circuit evaluations (as below) lead to wrong results – at least in Jython 2.1:
seqa = map(lambda s: s.isdigit() and int(s) or s, re.findall('\d+|\w+', vA.replace('-SNAPSHOT', '')))
seqb = map(lambda s: s.isdigit() and int(s) or s, re.findall('\d+|\w+', vB.replace('-SNAPSHOT', '')))