 <p>From python <a href="http://docs.python.org/library/string.html" rel="nofollow noreferrer">docs</a>:</p> <blockquote> <p>Advanced usage: you can derive subclasses of Template to customize the placeholder syntax, delimiter character, or the entire regular expression used to parse template strings. To do this, you can override these class attributes:</p> <ul> <li><p>delimiter – This is the literal string describing a placeholder introducing delimiter. The default value $. Note that this should not be a regular expression, as the implementation will call re.escape() on this string as needed.</p></li> <li><p>idpattern – This is the regular expression describing the pattern for non-braced placeholders (the braces will be added automatically as appropriate). The default value is the regular expression [_a-z][_a-z0-9]*.</p></li> </ul> </blockquote> <p>Example:</p> <pre><code>from string import Template class MyTemplate(Template): delimiter = '#' idpattern = r'[a-z][_a-z0-9]*' &gt;&gt;&gt; s = MyTemplate('#who likes $what') &gt;&gt;&gt; s.substitute(who='tim', what='kung pao') 'tim likes $what' </code></pre> <hr> <p>In python 3:</p> <blockquote> <p><em>New in version 3.2.</em></p> <p>Alternatively, you can provide the entire regular expression pattern by overriding the class attribute pattern. If you do this, the value must be a regular expression object with four named capturing groups. The capturing groups correspond to the rules given above, along with the invalid placeholder rule:</p> <ul> <li>escaped – This group matches the escape sequence, e.g. $$, in the default pattern.</li> <li>named – This group matches the unbraced placeholder name; it should not include the delimiter in capturing group.</li> <li>braced – This group matches the brace enclosed placeholder name; it should not include either the delimiter or braces in the capturing group.</li> <li>invalid – This group matches any other delimiter pattern (usually a single delimiter), and it should appear last in the regular expression.</li> </ul> </blockquote> <p>Example:</p> <pre><code>from string import Template import re class TemplateClone(Template): delimiter = '$' pattern = r''' \$(?: (?P&lt;escaped&gt;\$) | # Escape sequence of two delimiters (?P&lt;named&gt;[_a-z][_a-z0-9]*) | # delimiter and a Python identifier {(?P&lt;braced&gt;[_a-z][_a-z0-9]*)} | # delimiter and a braced identifier (?P&lt;invalid&gt;) # Other ill-formed delimiter exprs ) ''' class TemplateAlternative(Template): delimiter = '[-' pattern = r''' \[-(?: (?P&lt;escaped&gt;-) | # Expression [-- will become [- (?P&lt;named&gt;[^\[\]\n-]+)-\] | # -, [, ], and \n can't be used in names \b\B(?P&lt;braced&gt;) | # Braced names disabled (?P&lt;invalid&gt;) # ) ''' &gt;&gt;&gt; t = TemplateClone("$hi sir") &gt;&gt;&gt; t.substitute({"hi": "hello"}) 'hello sir' &gt;&gt;&gt; ta = TemplateAlternative("[-hi-] sir") &gt;&gt;&gt; ta.substitute({"hi": "have a nice day"}) 'have a nice day sir' &gt;&gt;&gt; ta = TemplateAlternative("[--[-hi-]-]") &gt;&gt;&gt; ta.substitute({"hi": "have a nice day"}) '[-have a nice day-]' </code></pre> <p>Apparently it is also possible to just omit any of the regex groups <code>escaped</code>, <code>named</code>, <code>braced</code> or <code>invalid</code> to disable it.</p>