import re


def get_tag_value(string, pre, post, tagtype=float, greedy=True):
    """
    Extracts the value of a tag from a string.

    Parameters
    -----------------

    pre : str
        regular expression to match before the the tag value

    post : str | list | tuple
        regular expression to match after the the tag value

        if list than the regular expressions will be combined into the regular expression (?=post[0]|post[1]|..)

    tagtype : str | float | int
        the type to which the tag value should be converted to

    greedy : bool
        Whether the regular expression is greedy or not.

    Returns
    ---------------
    Tag value if found, None otherwise

    Example
    ------------

    get_tag_value('PID_23.5.txt', pre=r'PID_' , post='(?=_|\.txt)') should return 23.5
    get_tag_value('PID_23.5_.txt', pre=r'PID_', post='(?=_|\.txt)') should return 23.5
    get_tag_value('PID_23_5_.txt', pre=r'PID_', post='(?=_|\.txt)') should return 23
    get_tag_value('PID_23.txt', pre=r'PID_', post='.txt') should return 23
    get_tag_value('PID.txt', pre=r'PID_', post='.txt') should return None
    """
    greedy = '?' if greedy else ''  # For greedy search

    if isinstance(post, (list, tuple)):
        post = '(?=' + '|'.join(post) + ')'

    tag_list = re.findall(r'{pre}(.+{greedy}){post}'.format(pre=pre, post=post, greedy=greedy),
                          string)

    if len(tag_list) > 1:
        raise ValueError('More than one matching pattern found... check filename')
    elif len(tag_list) == 0:
        return None
    else:
        return tagtype(tag_list[0])