'crop the match with given Match objects or spans tuples
:param crops:
:type crops: list or object
:return: a list of Match objects
:rtype: list[Match]'

def crop(self, crops, predicate=None, index=None):

    if ((not is_iterable(crops)) or ((len(crops) == 2) and isinstance(crops[0], int))):
        crops = [crops]
    initial = copy.deepcopy(self)
    ret = [initial]
    for crop in crops:
        if hasattr(crop, 'span'):
            (start, end) = crop.span
        else:
            (start, end) = crop
        for current in list(ret):
            if ((start <= current.start) and (end >= current.end)):
                ret.remove(current)
            elif ((start >= current.start) and (end <= current.end)):
                right = copy.deepcopy(current)
                current.end = start
                if (len(current) <= 0):
                    ret.remove(current)
                right.start = end
                if (len(right) > 0):
                    ret.append(right)
            elif ((end <= current.end) and (end > current.start)):
                current.start = end
            elif ((start >= current.start) and (start < current.end)):
                current.end = start
    return filter_index(ret, predicate, index)
