def parse_range(s, maximum=0):
    """
    Parses a range string.
    
    :param s:
    :param maximum:
    :return:
    """
    maximum -= 1
    splits = s.replace(' ', '').replace(';', ',').split(',')
    ranges = []
    remove = []
    not_values = False
    for frag in splits:
        if frag[0] == '~':
            not_values = not not_values
            frag = frag[1:]
        if '-' in frag:
            f, t = frag.split('-')
            interval = 1
            if '%' in t:
                t, _interval = t.split('%')
                interval = int(_interval)
            if t == '':
                t = maximum
            f, t = int(f), int(t)
            t = min(t, maximum)
            parsed_fragment = range(f, t + 1, interval)
        else:
            parsed_fragment = [int(frag)]
        if not_values:
            remove += parsed_fragment
        else:
            ranges += parsed_fragment
    return list(sorted(set(ranges) - set(remove)))
