CODE-0002 · gpt-5.5 (high)import re
_SEMVER_RE = re.compile(
r"(0|[1-9][0-9]*)"
r"\."
r"(0|[1-9][0-9]*)"
r"\."
r"(0|[1-9][0-9]*)"
r"(?:-((?:0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))*))?"
r"(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?"
)
def parse_semver(s):
if not isinstance(s, str):
return None
match = _SEMVER_RE.fullmatch(s)
if match is None:
return None
major, minor, patch, prerelease, build = match.groups()
return {
"major": int(major),
"minor": int(minor),
"patch": int(patch),
"prerelease": prerelease,
"build": build,
}