from functools import reduce


def _parse_address(full_address):
    """Parse a string containing a range address.

    Parse an Excel range address into a sheet name and a range specification.

    Example:
        ```_parse_address("'my sheet'!A1:X100")``` would return
        ```("my_sheet", "A1:X100")```.
    """
    splitaddr = full_address.split("!")
    if len(splitaddr) == 1:
        sheet_name = None
        address = splitaddr[0]
    elif len(splitaddr) == 2:
        characters_to_strip = list("'<>=")
        sheet_name = reduce(
            lambda x, y: x.strip(y), characters_to_strip, splitaddr[0]
        )
        sheet_name = sheet_name.split("]")[-1]
        address = splitaddr[1].strip(">")
    else:
        raise ValueError(
            "Invalid address in _parse_address: "
            + 'cannot contain multiple "!" characters'
        )
    return (sheet_name, address)