def find_first_level_groups_span(string, enclosing):
    """Return a list of pairs (start, end) for the groups delimited by the given
    enclosing characters.
    This does not return nested groups, ie: '(ab(c)(d))' will return a single group
    containing the whole string.

    >>> find_first_level_groups_span('abcd', '()')
    []

    >>> find_first_level_groups_span('abc(de)fgh', '()')
    [(3, 7)]

    >>> find_first_level_groups_span('(ab(c)(d))', '()')
    [(0, 10)]

    >>> find_first_level_groups_span('ab[c]de[f]gh(i)', '[]')
    [(2, 5), (7, 10)]
    """
    opening, closing = enclosing
    depth = []  # depth is a stack of indices where we opened a group
    result = []
    for i, c, in enumerate(string):
        if c == opening:
            depth.append(i)
        elif c == closing:
            try:
                start = depth.pop()
                end = i
                if not depth:
                    # we emptied our stack, so we have a 1st level group
                    result.append((start, end + 1))
            except IndexError:
                # we closed a group which was not opened before
                pass

    return result