Python regex substitution using a dictionary
Question: I have the following regex to parse access strings inside brackets and remove
them:

    
    
    >>> a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
    >>> re.sub(r'\[\s?(.*?)\s?\]',r'\1',a)
    'abcdefghijklmnop'
    

But what I want to do is have what is in brackets target a dictionary. Let's
say I have the following dictionary:

    
    
    d = {'b':2,'g':7,'j':10,'p':16}
    

when I run my desired regex it should print the string: `'a2cdef7hi10klmno16'`

However, I cannot simply have the replace part of `sub` be `d['\1']` because
there will be a `KeyError: '\x01'`.

**Is there any simple way to replace a pattern with a dictionary responding to
a capture in regex?**


Answer: You can use
[`format`](http://docs.python.org/2/library/stdtypes.html#str.format),
assuming `a` doesn't contain substrings of the form `{...}`:

    
    
    >>> import re
    >>> a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
    >>> d = {'b':2,'g':7,'j':10,'p':16}
    >>> 
    >>> re.sub(r'\[\s?(.*?)\s?\]',r'{\1}',a).format(**d)
    'a2cdef7hi10klmno16'
    

Or you can use a `lambda`:

    
    
    >>> re.sub(r'\[\s?(.*?)\s?\]', lambda m: str(d[m.group(1)]), a)
    'a2cdef7hi10klmno16'
    

* * *

The `lambda` solution appears to be much faster:

    
    
    >>> from timeit import timeit
    >>>
    >>> setup = """
    ... import re
    ... a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
    ... d = {'b':2,'g':7,'j':10,'p':16}
    ... """
    >>>
    >>> timeit(r"re.sub(r'\[\s?(.*?)\s?\]',r'{\1}',a).format(**d)", setup)
    13.796708106994629
    >>> timeit(r"re.sub(r'\[\s?(.*?)\s?\]', lambda m: str(d[m.group(1)]), a)", setup)
    6.593755006790161
    

