import re


def match_rule(target, rule):
    """
    Match rule to a target.

    Parameters
    ----------
    target : dict
        Dictionary containing [(key, value), ...].
        Keys must be str, values must be str or None.
    rule : dict
        Dictionary containing [(key, match), ...], to be matched
        to *target*. Match can be str specifying a regexp that must
        match target[key], or None. None matches either None
        or a missing key in *target*. If match is not None,
        and the key is missing in *target*, the rule does not match.

    Returns
    -------
    matched : bool
        Whether the rule matched. The rule matches if
        all keys match.

    """
    for key, value in rule.items():
        if value is None:
            if key in target and target[key] is not None:
                return False
        elif key not in target or target[key] is None:
            return False
        else:
            w = str(target[key])
            m = re.match(str(value), w)
            if m is None or m.end() != len(w):
                return False

    # rule matched
    return True