6、shelve模块
shelve模块用来保存数据到文件中
(1)open()函数
l open()函数用来打开指定的文件(如果文件不存在则创建),返回shelf对象
l shelf对象是一个类Dictionary对象,只是key值必须是字符串
>>> import shelve
>>> s = shelve.open(r'c:/test.dat')
>>> s['x'] = ['a', 'b', 'c']
(2)需要注意的陷阱
l 下面的写法并不会达到预期目的:
>>> s['x'].append('d')
>>> s['x']
['a', 'b', 'c']
l 解决的方法是使用临时变量重新赋值
>>> temp = s['x']
>>> temp.append('d')
>>> s['x'] = temp
>>> s['x']
['a', 'b', 'c', 'd']
(3)close()
l 保存并关闭文件
>>> s.close()
7、re模块
re模块用来支持正则表达式处理。关于正则表达式的内容这里不多说了。
(1)compile(pattern[, flags])
l 将正则表达式字符串转换为pattern对象,用于更有效的匹配操作
(2)search(pattern, string[, flags])
l 查找指定的字符串,找到匹配指定的正则表达式的第一个子串;找到返回MatchObject对象(后面讲述),没找到返回None
(3)match(pattern, string[, flags])
l 检查指定的字符串开始是否匹配指定的正则表达式,返回值同search
l match()函数不必匹配整个字符串,如果需要匹配整个字符串,在正则表达式最后加$
(4)split(pattern, string[, maxsplit=0])
l split()函数类似于String的split()函数,但是允许使用正则表达式作为分割字符串
>>> some_text = 'alpha, beta,,,,gamma delta'
>>> re.split('[, ]+', some_text)
['alpha', 'beta', 'gamma', 'delta']
(5)findall(pattern, string)
l 返回指定字符串中匹配指定正则表达式的子串List
(6)sub(pat, repl, string[, count=0])
l 将指定字符串中匹配指定正则表达式的子串替换为repl返回(后面详细讲述)
l repl可以是用来进行替换处理的函数,这时函数有一个MatchObject参数,并返回替换的字符串
(7)escape(string)
l 转义指定字符串中所有正则表达式操作符返回
(8)MatchObject和分组
l 正则表达式中的分组就是用括号括起来的子模式(正则表达式)
l re模块的函数在匹配到指定模式(正则表达式),返回MatchObject对象,包含分组信息:MatchObject.group(0)返回整个匹配的字符串,MatchObject.group(1)返回第一个匹配子模式的子串,以此类推
>>> m = re.match(r'www/.(.*)/..{3}', 'www.python.org')
>>> m.group()
'www.python.org'
>>> m.group(1)
'python'
l group()函数不指定参数,使用缺省值0
l start()函数返回指定分组匹配的子串在字符串中的开始索引值
>>> m.start(1)
4
l end()函数返回指定分组匹配的子串在字符串中的结束索引值
>>> m.end(1)
10
l span()函数返回指定分组匹配的子串在字符串中的开始和结束索引值Tuple
>>> m.span(1)
(4, 10)
(9)分组在字符串替换中的应用
l 在re.sub()函数中使用分组替换字符串:在替换字符串中所有//n的形式都会替换成分组n匹配的子串,下面是一个将“*something*”替换成“<em>something</em>”的例子:
>>> emphasis_pattern = r'/*([^/*]+)/*'
>>> re.sub(emphasis_pattern, r'<em>/1</em>', 'Hello, *world*!')
'Hello, <em>world</em>!'
l 正则表达式中的重复操作符具有贪婪性,会尽可能多的匹配。下面的例子并不是所期望的结果:
>>> emphasis_pattern = r'/*(.+)/*'
>>> re.sub(emphasis_pattern, r'<em>/1</em>', '*This* is *it*!')
'<em>This* is *it</em>!'
l 这里的正则表达式和前面的区别是没有限制“*”对中间的“*”,由于“+”的贪婪性,会匹配到最后一个“*”
l 解决的方法是在重复操作符的后面加“?”,使其不具有贪婪性:
>>> emphasis_pattern = r'/*(.+?)/*'
>>> re.sub(emphasis_pattern, r'<em>/1</em>', '*This* is *it*!')
'<em>This</em> is <em>it</em>!'
(10)简单模板系统的例子
l 主要功能:
Ø 将[something](模板字段)中something作为Python表达式计算,用结果来替换模板字段
Ø 对模板字段中的赋值语句进行赋值操作,以便赋值结果用于表达式计算
Ø 下面是转换的例子:
'The sum of 7 and 9 is [7 + 9].'
'[name="Mr. Gumby"]Hello, [name]'
Ø 转换结果如下:
'The sum of 7 and 9 is 16.'
'Hello, Mr. Gumby'
l 下面是程序清单:
# templates.py
import 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 in scope
# ...and return an empty string:
return ''
# Get all the text as a single string:
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)
l 定义匹配模板字段的正则表达式
l 定义用于表达式计算的作用范围Dictionary(scope)
l 对匹配的内容使用eval()函数在scope作用范围进行表达式计算,以字符串形式返回;
l 如果发生SyntaxError异常,可能是赋值语句,使用exec在scope作用范围执行语句
l 使用re.sub()函数进行模板字段替换
l 这里还用到一个技巧就是:每行内容追加到List中,最后使用join()函数连接。这比使用“+”直接连接字符串要高效得多
l 由于使用了fileinput,执行时可以指定多个文件,所以可以将赋值的内容独立于模板内容,分别放在两个不同的文件中,但执行时赋值内容文件必须在前面指定