Here's a hybrid solution, using pyparsing to parse your input pattern string (p), and transforming it into a regexp string. Then uses re.match using the regexp to process string (s), and then builds a dictionary from the matched groups.
Download pyparsing at http://pyparsing.sourceforge.net. -- Paul =================== import re from pyparsing import Word,OneOrMore previousKeys = [] def createUpperKey(s,l,t): if t[0] not in previousKeys: ret = "(?P<%s>.*)" % t[0] previousKeys.append(t[0]) else: ret = "(?P=%s)" % t[0] return ret lowers = "abcdefghijklmnopqrstuvwxyz" uppers = lowers.upper() lowerLetter = Word(lowers,max=1) upperLetter = Word(uppers,max=1).setParseAction(createUpperKey) pattern = OneOrMore( lowerLetter | upperLetter ) def fill(s,p): # reset keys found in p-patterns del previousKeys[:] # create regexp by running pyparsing transform regexp = pattern.transformString(p) + "$" # create dict from re-matched groups match = re.match(regexp,s) if match: ret = dict( [ (k,match.group(k)) for k in previousKeys ] ) else: ret = dict() return ret tests = [ ('ab','aA'), ('ab','Ab'), ('bb','Aa'), ('aa','Aa'), ('aa','Ab'), ('abb','aA'), ('aba','aAa'), ('abbba','aAa'), ('abbbaba','aAa'), ('abb','aAa'), ('abab','aAaA'), ('abac','aAaA'), ('abac','aAaB'), ] for t in tests: print t,fill( *t ) ================ Gives: ('ab', 'aA') {'A': 'b'} ('ab', 'Ab') {'A': 'a'} ('bb', 'Aa') {} ('aa', 'Aa') {'A': 'a'} ('aa', 'Ab') {} ('abb', 'aA') {'A': 'bb'} ('aba', 'aAa') {'A': 'b'} ('abbba', 'aAa') {'A': 'bbb'} ('abbbaba', 'aAa') {'A': 'bbbab'} ('abb', 'aAa') {} ('abab', 'aAaA') {'A': 'b'} ('abac', 'aAaA') {} ('abac', 'aAaB') {'A': 'b', 'B': 'c'} -- http://mail.python.org/mailman/listinfo/python-list