1.1.3 高级模板
可以调整string.Template在模板体中查找变量名所使用的正则表达模式,以改变它的默认语法。为此,一种简单的方法是修改delimiter和idpattern类属性。
import string
class MyTemplate(string.Template):
delimiter = '%'
idpattern = '[a-z]+_[a-z]+'
template_text = '''
Delimiter:%%
Replaced:%with_underscore
Ignored:%notunderscored
'''
d = {
'with_underscore' : 'repaced',
'notunderscored' : 'not replaced',
}
t = MyTemplate(template_text)
print('Modified ID pattern:')
print(t.safe_substitute(d))
在这个例子中,替换规则已经改变,定界符是%而不是$,而且变量名中间的某个位置必须包含一个下划线。模式%notunderscored不会被替换为任何字符串,因为它不包含下划线字符。
运行结果:
要完成更复杂的修改,可以覆盖pattern属性定义一个全新的正则表达式、所提供的模式必须包含4个命名组,分别捕获转义定界符,命名变量、加括号的变量名和不合法的定界符模式。
import string
t = string.Template('$var')
print(t.pattern.pattern)
t.pattern的值是一个已编译正则表达式,不过可以通过它的pattern属性得到原来的字符串。
运行结果:
下面这个例子定义了一个新模式以创建一个新的模板类型,这里使用{{var}}作为变量语法。
import re
import string
class MyTemplate(string.Template):
delimiter = '{{'
pattern = r'''
\{\{(?:
(?P<escaped>\{\{)|
(?P<named>[_a-z][_a-z0-9]*)\}\}|
(?P<braced>[_a-z][_a-z0-9]*)\}\}|
(?P<invalid>)
)
'''
t = MyTemplate('''
{{{{
{{var}}
''')
print('MATCHES:',t.pattern.findall(t.template))
print('SUBSTITUTE:',t.safe_substitute(var='replacement'))
必须分别提供named和braced模式,尽管它们实际上是一样的。
运行结果: