def compare_semver(v1, v2):
    def parse(v):
        parts = v.split('-', 1)
        main = [int(x) for x in parts[0].split('.')]
        pre = parts[1].split('.') if len(parts) > 1 else None
        return main, pre

    m1, p1 = parse(v1)
    m2, p2 = parse(v2)

    for a, b in zip(m1, m2):
        if a < b: return -1
        if a > b: return 1

    if p1 == p2:
        return 0
    if p1 is None:
        return 1
    if p2 is None:
        return -1

    for a, b in zip(p1, p2):
        is_a_digit = a.isdigit()
        is_b_digit = b.isdigit()
        if is_a_digit and is_b_digit:
            ia, ib = int(a), int(b)
            if ia < ib: return -1
            if ia > ib: return 1
        elif not is_a_digit and not is_b_digit:
            if a < b: return -1
            if a > b: return 1
        else:
            # Numeric identifiers have lower precedence than non-numeric identifiers.
            return -1 if is_a_digit else 1

    if len(p1) < len(p2): return -1
    if len(p1) > len(p2): return 1
    return 0
