I'm looking for a foolproof way to sort a list of semantic version strings in python3 without use of the third-party semver module.
For instance, if I have a list like this:
versions_list = ["1.0.0", "1.0.0-alpha", "11.3.3", "1.0.12", "1.0.0-0", "1.0.0+rc1", ]
I'd like it to sort to the rules of semantic versioning
# Oldest to "Newest"
versions_list = ['0.0.1', '1.0.0-0', '1.0.0-alpha', '1.0.0+rc1', '1.0.0', '1.0.12', '11.3.3']
This is the best I could come up with, utilizing the semver regex from https://semver.org/
# From semver.org
>>> semver = re.compile(r'^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$')
# Unsorted
>>> l = ["0.0.1", "1.0.0", "1.0.0-alpha", "11.3.3", "1.0.12", "1.0.0-0", "1.0.0+rc1"]
# Sort via sorted() and lambda creating list from regex match groups
>>> sorted_l = sorted(l, key=lambda w: [[int(x.group('major')), int(x.group('minor')), int(x.group('patch')), str(x.group('prerelease') or 'zzzzzz'), str(x.group('buildmetadata') or 'zzzzzzz')] for x in [semver.match(w)]])
>>> print(sorted_l)
['0.0.1', '1.0.0-0', '1.0.0-alpha', '1.0.0+rc1', '1.0.0', '1.0.12', '11.3.3']
But I was wondering if there is a way without the hack I had using the 'zzzzzzz' on the None/no match groups.