In [120]:
import re

CONTAINER = r'(?P<pattern>{})'
ARG_PATTERN = CONTAINER.format('\{\{(?P<arg>.*?)\}\}')
IN_EX_PATTERN = r'{}|(.)'.format(ARG_PATTERN)

template = 'Test\n{{one}}\ntest\n{{two}}\n{{two}}'
it = re.finditer(ARG_PATTERN, template)

In [121]:
re.findall(ARG_PATTERN, template)


Out[121]:
[('{{one}}', 'one'), ('{{two}}', 'two'), ('{{two}}', 'two')]

In [122]:
def extract_args(template):
	"""
	From given template, find all |arguments| inside.
	"""
	return {match.groupdict()['arg'] for match in re.finditer(ARG_PATTERN, template)}

In [123]:
extract_args(template)


Out[123]:
{'one', 'two'}

In [ ]:


In [124]:
re.findall(IN_EX_PATTERN, template, re.DOTALL)


Out[124]:
[('', '', 'T'),
 ('', '', 'e'),
 ('', '', 's'),
 ('', '', 't'),
 ('', '', '\n'),
 ('{{one}}', 'one', ''),
 ('', '', '\n'),
 ('', '', 't'),
 ('', '', 'e'),
 ('', '', 's'),
 ('', '', 't'),
 ('', '', '\n'),
 ('{{two}}', 'two', ''),
 ('', '', '\n'),
 ('{{two}}', 'two', '')]

In [125]:
def build_text(template, arg2items):
    """
    Make the output text based on template
    """
    output = []
    for matches in re.findall(IN_EX_PATTERN, template, re.DOTALL):
        if matches[0] != '': # something to replace
            output.append(arg2items[matches[1]].pop(0))
        else:
            output.append(matches[2])
    return ''.join(output)

In [127]:
arg2items = {'one': ['bob', 'alice'],
             'two': ['kitty', 'bunny']}
build_text(template, arg2items)


Out[127]:
'Test\nbob\ntest\nkitty\nbunny'

In [116]:
re.findall(IN_EX_PATTERN, template)


Out[116]:
[('', '', 'Test'),
 ('{{one}}', 'one', ''),
 ('', '', 'test'),
 ('{{two}}', 'two', ''),
 ('{{two}}', 'two', '')]

In [88]:
IN_EX_PATTERN


Out[88]:
'(?P<pattern>\\|(?P<arg>\\S*?)\\|)|(.+)'

In [119]:
s = 'firefox is not a fox'
p = r'(fox)|(.)'
re.findall(p, s)


Out[119]:
[('', 'f'),
 ('', 'i'),
 ('', 'r'),
 ('', 'e'),
 ('fox', ''),
 ('', ' '),
 ('', 'i'),
 ('', 's'),
 ('', ' '),
 ('', 'n'),
 ('', 'o'),
 ('', 't'),
 ('', ' '),
 ('', 'a'),
 ('', ' '),
 ('fox', '')]

In [56]:
"""
Test

|one|
test
|two|
|two|
"""


Out[56]:
'\nTest\n\n|one|\ntest\n|two|\n|two|\n'

In [ ]: