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', '')))