from pyparsing import * from string import * def action(s, loc, toks): print('s', type(s), s) print('loc', type(loc), loc) print('toks', type(toks), toks) return ['<'] + list(toks) + ['>'] pattern = Suppress('[') + Word(digits) + '-' + Word(digits).setParseAction(action) + Suppress(']') pattern.parseString('[0-9]') # >>> pattern.parseString('test[0-9]test') # ParseException: Expected "[" (at char 0), (line:1, col:1) pattern.searchString('test[0-9]test') pattern.searchString('test[0-9]test[0-9]') list(pattern.scanString('test[0-9]test')) list(pattern.scanString('test[0-9]test[0-9]')) pattern.transformString('test[0-9]test[0-9]') text = SkipTo(StringEnd() | '[') numeric = Suppress('[') + Word(digits) + Suppress('-') + Word(digits) + Suppress(']') pattern = ZeroOrMore(text | numeric) def skip_empty(toks): if not toks[0]: raise ParseException('must be not empty') text.addParseAction(skip_empty) pattern.parseString('test[0-9]test[0-9]') pattern.parseString('te\[\]st\\\\[0-9]test[0-9]') escape = (Literal('\\\\').addParseAction(replaceWith('\\')) | Literal('\\[').addParseAction(replaceWith('[')) | Literal('\\]').addParseAction(replaceWith(']'))) text = SkipTo(StringEnd() | '[', ignore=escape).setParseAction(skip_empty) pattern = ZeroOrMore(text | numeric) pattern.parseString('te\[\]st\\\\[0-9]test[0-9]') def unescape(toks): return [escape.transformString(item) for item in toks] text.addParseAction(unescape) pattern.parseString('te\[\]st\\\\[0-9]test[0-9]') def text_block(toks): return [iter(toks)] def numeric_block(toks): from_value, to_value = toks return [map(str, range(int(from_value), int(to_value) + 1))] text.addParseAction(text_block) numeric.addParseAction(numeric_block) pattern.parseString('te\[\]st\\\\[0-9]test[0-9]') from itertools import product def iterator(string): return (''.join(items) for items in product(*pattern.parseString(string))) len(list(iterator('te\[\]st\\\\[0-9]test[0-9]'))) list(iterator('te\[\]st\\\\[0-9]test[0-9]'))[:3] list(iterator('te\[\]st\\\\[0-9]test[0-9]'))[-3:]