def template2regex(template, ranges=None):
    if len(template) and -1 < template.find('|') < len(template) - 1:
        raise InvalidTemplateError("'|' may only appear at the end, found at position %d in %s" % (template.find('|'), template))
    if ranges is None:
        ranges = DEFAULT_RANGES
    anchor = True
    state = S_PATH
    if len(template) and template[-1] == '|':
        anchor = False
    params = []
    bracketdepth = 0
    result = ['^']
    name = ""
    pattern = "[^/]+"
    rangename = None
    for c in template_splitter.split(template):
        if state == S_PATH:
            if len(c) > 1:
                result.append(re.escape(c))
            elif c == '[':
                result.append("(")
                bracketdepth += 1
            elif c == ']':
                bracketdepth -= 1
                if bracketdepth < 0:
                    raise InvalidTemplateError("Mismatched brackets in %s" % template)
                result.append(")?")
            elif c == '{':
                name = ""
                state = S_TEMPLATE
            elif c == '}':
                raise InvalidTemplateError("Mismatched braces in %s" % template)
            elif c == '|':
                pass
            else:
                result.append(re.escape(c))
        else:
            if c == '}':
                if rangename and rangename in ranges:
                    result.append("(?P<%s>%s)" % (name, ranges[rangename]))
                else:
                    result.append("(?P<%s>%s)" % (name, pattern))
                params.append(name)
                state = S_PATH
                rangename = None
            else:
                name = c
                if name.find(":") > -1:
                    name, rangename = name.split(":")
    if bracketdepth != 0:
        raise InvalidTemplateError("Mismatched brackets in %s" % template)
    if state == S_TEMPLATE:
        raise InvalidTemplateError("Mismatched braces in %s" % template)
    if anchor:
        result.append('$')
    return "".join(result), params