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 <a href="//sebthom.de/">Sebastian Thomschke</a>
- @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', '')))