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

    main1, pre1 = parse(v1)
    main2, pre2 = parse(v2)

    for m1, m2 in zip(main1, main2):
        if m1 > m2: return 1
        if m1 < m2: return -1

    if pre1 is None and pre2 is None:
        return 0
    if pre1 is None:
        return 1
    if pre2 is None:
        return -1

    for p1, p2 in zip(pre1, pre2):
        is_p1_digit = p1.isdigit()
        is_p2_digit = p2.isdigit()

        if is_p1_digit and is_p2_digit:
            n1, n2 = int(p1), int(p2)
            if n1 > n2: return 1
            if n1 < n2: return -1
        elif not is_p1_digit and not is_p2_digit:
            if p1 > p2: return 1
            if p1 < p2: return -1
        else:
            # Numeric identifiers have lower precedence than non-numeric identifiers.
            return -1 if is_p1_digit else 1

    if len(pre1) > len(pre2):
        return 1
    if len(pre1) < len(pre2):
        return -1

    return 0
