CODE-0002 · kimi-k2.7-code (default)import re
def parse_semver(s):
if not isinstance(s, str):
return None
# Main pattern: MAJOR.MINOR.PATCH[-prerelease][+build]
# We need to validate leading zeros separately for numeric parts
pattern = r'^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$'
match = re.match(pattern, s)
if not match:
return None
major_str, minor_str, patch_str, prerelease, build = match.groups()
# Validate no leading zeros for major, minor, patch
for num_str in (major_str, minor_str, patch_str):
if len(num_str) > 1 and num_str[0] == '0':
return None
# Validate prerelease identifiers
if prerelease is not None:
prerelease_ids = prerelease.split('.')
for pid in prerelease_ids:
if not pid: # empty identifier (e.g., consecutive dots)
return None
# Check if numeric identifier has leading zeros
if pid.isdigit():
if len(pid) > 1 and pid[0] == '0':
return None
# else: non-numeric, valid characters already checked by regex
# Validate build identifiers (just check non-empty, regex already checks chars)
if build is not None:
build_ids = build.split('.')
for bid in build_ids:
if not bid: # empty identifier
return None
return {
"major": int(major_str),
"minor": int(minor_str),
"patch": int(patch_str),
"prerelease": prerelease,
"build": build
}