CODE-0002 · gemini-3.1-flash-lite (default)
import re

def parse_semver(s):
    if not isinstance(s, str):
        return None

    pattern = (
        r'^(?P<major>0|[1-9]\d*)\.'
        r'(?P<minor>0|[1-9]\d*)\.'
        r'(?P<patch>0|[1-9]\d*)'
        r'(?:-(?P<prerelease>(?:0|[1-9]\d*|[0-9a-zA-Z-]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|[0-9a-zA-Z-]*[a-zA-Z-][0-9a-zA-Z-]*))*))?'
        r'(?:\+(?P<build>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
    )

    match = re.match(pattern, s)
    if not match:
        return None

    groups = match.groupdict()

    # Further validation for prerelease numeric segments
    if groups['prerelease']:
        parts = groups['prerelease'].split('.')
        for part in parts:
            if part.isdigit() and len(part) > 1 and part.startswith('0'):
                return None

    return {
        "major": int(groups['major']),
        "minor": int(groups['minor']),
        "patch": int(groups['patch']),
        "prerelease": groups['prerelease'],
        "build": groups['build']
    }