本文主要讲解Python实现的一个简单的文本模板系统(Template System)。
一、模版系统
先看效果:
1,案例一
已知文件“a_simple_template_example.txt”的内容如下:
[x = 2]
[y = 3]
The sum of [x] and [y] is [x + y].
经过“Template System”处理后结果如下:
如上图,它输出了:“The sum of 2 and 3 is 5.”
案例二:
已知数据文件“magnus.txt”的内容如下:
[name = 'Magnus Lie Hetland' ]
[email = 'magnus@foo.bar' ]
[language = 'python' ]
模版文件“template.txt”内容如下:
[import time]
Dear [name],I would like to learn how to program. I hear you use
the [language] language a lot -- is it something I
should consider?And, by the way, is [email] your correct email address?Fooville, [time.asctime()]Oscar Frozzbozz
经过“Template System”处理后,输出如下:
如上图,这个模版系统将数据成功的嵌入了模板,并生成了一份邮件。
有没有觉得这个模版系统很神奇?
下面我们就来一探系统的真相。
二、技术原理
从上面的两个案例可以看出,这个“Template System”不仅进行了文本匹配和替换,而且执行了“加法”运算,此外还导入了“当前时间”。这些看起来挺复杂的,让我们细细分析下需要哪些技术:
1)正则表达式 - regular expression (chapter 10)
python的“re”库,用于匹配目标字符串和剥离目标字符串。
事实上,re 是一个非常有效的文本处理库,需要重点掌握。相关的入门资料:
https://docs.python.org/3.5/library/re.html?highlight=re#module-re
https://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
2)eval - evaluate (chapter 5)
python内置的eval函数,可以计算字符串表达式的值。
3)try/except - (chapter 8)
在使用eva函数时,不是所有字符串都适合计算。这时,可以用try/except将eva包裹,如果抛出“SyntaxError”,则可以换成exec函数来执行。
4)exec - execute (chapter 5)
python内置的exec函数,可以执行字符串表达式。exec和eval都是在一个临时的scope中。
5)re.sub - substitute
将计算的结果替换回原文。
这么一分解,似乎也不是那么复杂!
三、代码探索
# templates.pyimport fileinput, re# Matches fields enclosed in square brackets:
field_pat = re.compile(r'\[(.+?)\]')# We'll collect variables in this:
scope = {}# This is used in re.sub:
def replacement(match):code = match.group(1)try:# If the field can be evaluated, return it:return str(eval(code, scope))except SyntaxError:# Otherwise, execute the assignment in the same scope ...exec(code, scope)# ... and return an empty string:return ''# Get all the text as a single string:# (There are other ways of doing this; see Chapter 11)
lines = []
for line in fileinput.input():lines.append(line)
text = ''.join(lines)# Substitute all the occurrences of the field pattern:
print(field_pat.sub(replacement, text))"""
f =open('output.txt', 'w')
f.write(field_pat.sub(replacement, text))
f.close()
"""
简单来说,这个程序做了这些事:
1)定义了一个匹配方案(pattern),第6行;
2)创建一个dictionary,用于eval个exec计算。
3)设计一个替换函数。
4)用fileinput读写文件。
5)用re.sub进行替换操作。