@lru_cache(maxsize=SCANF_CACHE_SIZE)<EOL>def scanf_compile(format, collapseWhitespace=True):
format_pat = "<STR_LIT>"<EOL>cast_list = []<EOL>i = <NUM_LIT:0><EOL>length = len(format)<EOL>while i < length:<EOL><INDENT>found = None<EOL>for token, pattern, cast in scanf_translate:<EOL><INDENT>found = token.match(format, i)<EOL>if found:<EOL><INDENT>if cast: <EOL><INDENT>cast_list.append(cast)<EOL><DEDENT>groups = found.groupdict() or found.groups()<EOL>if groups:<EOL><INDENT>pattern = pattern % groups<EOL><DEDENT>format_pat += pattern<EOL>i = found.end()<EOL>break<EOL><DEDENT><DEDENT>if not found:<EOL><INDENT>char = format[i]<EOL>if char in "<STR_LIT>":<EOL><INDENT>format_pat += "<STR_LIT:\\>"<EOL><DEDENT>format_pat += char<EOL>i += <NUM_LIT:1><EOL><DEDENT><DEDENT>if DEBUG:<EOL><INDENT>print("<STR_LIT>" % (format, format_pat))<EOL><DEDENT>if collapseWhitespace:<EOL><INDENT>format_pat = re.sub(r'<STR_LIT>', r'<STR_LIT>', format_pat)<EOL><DEDENT>format_re = re.compile(format_pat)<EOL>return format_re, cast_list<EOL>
Translate the format into a regular expression

For example:
>>> format_re, casts = scanf_compile('%s - %d errors, %d warnings')
>>> print format_re.pattern
(\S+) \- ([+-]?\d+) errors, ([+-]?\d+) warnings

Translated formats are cached for faster reuse