2

This is my code that is not workin:

def myfunc(d):
    for name, pat in d.items():
        originalstring = pat
        pattern = '#\w+#'
        pattern_obj = re.compile(pattern)
        replacement_string = '('+d['\\1']+')'
        d[name] = pattern_obj.sub(replacement_string, originalstring)
    return d

I'm getting an error that says the:

KeyError: '\\1'
  • 1
    what's not working? Do you get an error? – msvalkon Apr 23 '14 at 08:04
  • @user3527631 how were you expecting this to work? `'\\1'` isn't a key, so you get a `KeyError`. – jonrsharpe Apr 23 '14 at 08:11
  • You are just compiling the pattern, not matching anything with it. Probably you have to call `re.find` and then use the result of that as a key or similar. – tobias_k Apr 23 '14 at 08:16
  • The problem is that you are accessing the dict with that key _before_ doing sub. The key is not interpreted as part of a regular expression but just a key that does not exist. – tobias_k Apr 23 '14 at 08:22

1 Answers1

1

If you need dynamic replacements, there's a functional form of re.sub for that. Also I think it'd be better to wrap the whole thing in a loop to handle replacements of arbitrary depth (in my example, range depends on int which in turn depends on digit):

import re

def make_patterns(patdict):
    old, new = patdict, {}
    while True:
        for name, pat in old.items():
            new[name] = re.sub(r'#(\w+)#',
                lambda m: old[m.group(1)],
                pat)
        if new == old:
            return old
        old, new = new, {}


d = dict(
    digit=r'\d',
    integer=r'[=-]?#digit##digit#*',
    range='#integer#-#integer#'
)

print make_patterns(d)

Result

 {'integer': '[=-]?\\d\\d*', 'range': '[=-]?\\d\\d*-[=-]?\\d\\d*', 'digit': '\\d'}
gog
  • 10,367
  • 2
  • 24
  • 38