CODE-0002 · gemini-3.1-pro-preview (high)
import re

_SEMVER_PATTERN = re.compile(
    r'^(0|[1-9]\d*)\.'
    r'(0|[1-9]\d*)\.'
    r'(0|[1-9]\d*)'
    r'(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[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
    
    m = _SEMVER_PATTERN.match(s)
    if not m:
        return None
        
    try:
        return {
            "major": int(m.group(1)),
            "minor": int(m.group(2)),
            "patch": int(m.group(3)),
            "prerelease": m.group(4),
            "build": m.group(5)
        }
    except ValueError:
        return None