CODE-0002 · claude-haiku-4-5 (default)import re
def parse_semver(s):
"""Parse a Semantic Versioning 2.0.0 version string.
Returns a dict with keys 'major', 'minor', 'patch', 'prerelease', 'build'
on success, or None if the string is not a valid SemVer version.
"""
if not isinstance(s, str):
return None
# Pattern for a valid SemVer string
# MAJOR.MINOR.PATCH[-prerelease][+build]
pattern = r'^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*))?(?:\+([a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*))?$'
match = re.match(pattern, s)
if not match:
return None
major, minor, patch, prerelease, build = match.groups()
# Validate prerelease identifiers if present
if prerelease:
identifiers = prerelease.split('.')
for identifier in identifiers:
if not identifier: # Empty identifier
return None
# Check if numeric identifier has leading zeros
if identifier.isdigit() and len(identifier) > 1 and identifier[0] == '0':
return None
# Build metadata identifiers are already validated by the regex
# (leading zeros are allowed in build metadata)
return {
'major': int(major),
'minor': int(minor),
'patch': int(patch),
'prerelease': prerelease if prerelease else None,
'build': build if build else None
}