6. 文本处理¶
6.1. string¶
6.1.1. string常量¶
常量 |
描述 |
---|---|
string.ascii_letter |
大小写字母一共52个 |
string.ascii_lowercase |
26个小写字母 |
string.ascii_uppercase |
26个的大写字母 |
string.digits |
10个数值字符 |
string.octdigits |
0-7 |
string.puctuaction |
标点符号 |
string.printable |
可打印的字符 |
string.whitespace |
空白字符 |
样例:
In [156]: string.ascii_letters
Out[156]: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
In [157]: string.ascii_lowercase
Out[157]: 'abcdefghijklmnopqrstuvwxyz'
In [158]: string.ascii_uppercase
Out[158]: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
In [159]: string.digits
Out[159]: '0123456789'
In [160]: string.hexdigits
Out[160]: '0123456789abcdefABCDEF'
In [161]: string.octdigits
Out[161]: '01234567'
In [162]: string.printable
Out[162]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_{|}~ \t\n\r\x0b\x0c'
In [163]: string.punctuation
Out[163]: '!"#$%&\'()*+,-./:;<=>?@[\\]^_{|}~'
In [164]: string.whitespace
Out[164]: ' \t\n\r\x0b\x0c'
6.1.2. 格式化样例¶
根据位置格式化
In [166]: '{0},{1},{2}'.format('a,','b','c')
Out[166]: 'a,,b,c'
In [167]: '{0},{1},{2}'.format('abc','bbb','cccc')
Out[167]: 'abc,bbb,cccc'
根据参数名格式化
In [168]: '{lon},{lat}'.format(lon=110,lat=45)
Out[168]: '110,45'
根据类属性格式化
In [170]: class point:
...: def __init__(self,x,y):
...: self.x,self.y=x,y
...: def __str__(self):
...: return 'point({self.x},{self.y})'.format(self=self)
...:
In [171]: str(point(2,4))
Out[171]: 'point(2,4)'
根据参数的条目
In [174]: coord=(3,4)
In [175]: 'x{0[0]},y{0[1]}'.format(coord)
Out[175]: 'x3,y4'
对齐
In [176]: '{:<30}'.format('left aligned')
Out[176]: 'left aligned '
In [177]: '{:>30}'.format('right aligned')
Out[177]: ' right aligned'
6.1.3. 模板字符串¶
样例:
In [178]: from string import Template
In [179]: s=Template('$who like $what')
In [180]: s.substitute(who="zhaojiedi",what="play game")
Out[180]: 'zhaojiedi like play game'
In [181]: d={"who":"zhaojiedi","what":"read book"}
In [182]: s.substitute(d)
Out[182]: 'zhaojiedi like read book'
6.2. re¶
re是regulare expression的简写。
正则表达式元字符
. 任意单个字符(除了换行),如果想包含换行,指定DOTALL标记
^ 开始位置锚定
$ 结束位置锚定
* 前面的分组或者字符重复任意次数,包括0次,也就是不重复。
+ 前面的分组或者字符至少一次
? 前面的分组或者字符0次或者1次,
*?,+? 终止贪婪模式,*,+都是尽可能多的通配,加上?不采用贪婪模式了。
{m} 前面的匹配m次数
{m,n} 前面的匹配m到n次,既包含m次也包含n次
{m,n}? 终止贪婪模式的
\ 转义功能
[] 集合中的任何任意
| |两侧的都可以,a|b代表既可以a也可以b
(...) 分组,中间可以写其他的正则表达式
(?...) 不创建组
(?<=...) 匹配到一个就不匹配下一个了。
\A 开始是字符串的
\b 匹配边界
\B 匹配不是开头或者单词的结果
\d 数值0-9
\D 不是\d的
\s 空白字符
\S 不是空白字符的
\w 匹配a-zA-Z0-9_这些字符
\W 除了\w 之外的字符
6.2.1. 模块内容¶
re.splitpattern, string, maxsplit=0, flags=0)
In [190]: re.split(r'\W+','words, words, words.')
Out[190]: ['words', 'words', 'words', '']
In [191]: re.split('[a-f]+','0a3B9',flags=re.IGNORECASE)
Out[191]: ['0', '3', '9']
re.findall(pattern, string, flags=0)
In [192]: re.findall("\w+",'words, words, words.')
Out[192]: ['words', 'words', 'words']
re.sub(pattern, repl, string, count=0, flags=0)
In [193]: re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
r'static PyObject*\npy_\1(void)\n{','def myfunc():')
Out[193]: 'static PyObject*\npy_myfunc(void)\n{'
如果pattern匹配了string,就把repl的应用替换为string。
6.2.2. 正则表达式对象¶
regex.search(string[, pos[, endpos]])
功能: 扫描字符串查找正则表达式产生匹配的第一个位置,并返回相应的匹配对象。 如果字符串中没有位置与模式匹配,则返回None;
In [1]: import re
In [2]: re.compile('d').search("dog")
Out[2]: <_sre.SRE_Match object; span=(0, 1), match='d'>
In [3]: re.compile('d').search("dog",1)
regex.match(string[, pos[, endpos]])
功能: 如果字符串开头的零个或多个字符匹配此正则表达式,则返回一个相应的匹配对象。 如果字符串与模式不匹配则返回None;
In [9]: pattern = re.compile("o")
In [10]: b=pattern.match("dog")
In [11]: print(b)
None
In [12]: c=pattern.match("dog",1)
In [13]: print(c)
<_sre.SRE_Match object; span=(1, 2), match='o'>
regex.fullmatch(string[, pos[, endpos]])
功能: 如果整个字符串匹配这个正则表达式,返回一个相应的匹配对象。 如果字符串与模式不匹配则返回None;
In [16]: pattern = re.compile("o[gh]")
In [17]: pattern.fullmatch("dog")
In [18]: pattern.fullmatch("ogre")
In [19]: pattern.fullmatch("og")
Out[19]: <_sre.SRE_Match object; span=(0, 2), match='og'>
In [20]: pattern.fullmatch("oh")
Out[20]: <_sre.SRE_Match object; span=(0, 2), match='oh'>
In [21]: pattern.fullmatch("ohh")
In [22]: pattern.fullmatch("ohh",0,2)
Out[22]: <_sre.SRE_Match object; span=(0, 2), match='oh'>
regex.split(string, maxsplit=0)
功能: 分割字符串,基本同re.split函数
In [23]: pattern =re.compile("\W+")
In [24]: pattern.split("world Zhaojiedi test")
Out[24]: ['world', 'Zhaojiedi', 'test']
6.2.3. 匹配对象¶
使用正则表达式匹配有成功有失败,可以使用简单的if判定结果状态。
match = re.search(pattern, string)
if match:
process(match)
match.group([group1, …])
功能: 返回一个或多个匹配的子组。
# 使用索引分组
In [25]: m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
In [26]: m.group()
Out[26]: 'Isaac Newton'
In [27]: m.group(0)
Out[27]: 'Isaac Newton'
In [28]: m.group(1)
Out[28]: 'Isaac'
In [29]: m.group(2)
Out[29]: 'Newton'
In [30]: m.group(1,2)
Out[30]: ('Isaac', 'Newton')
In [31]: m.groups()
Out[31]: ('Isaac', 'Newton')
# 使用命名分组
In [32]: m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)","zhao jiedi")
In [33]: m.group()
Out[33]: 'zhao jiedi'
In [35]: m.group("first_name")
Out[35]: 'zhao'
In [36]: m.group("last_name")
Out[36]: 'jiedi'
In [37]: m.group(0)
Out[37]: 'zhao jiedi'
In [38]: m.group(1)
Out[38]: 'zhao'
# 直接索引方式访问
In [39]: m[0]
Out[39]: 'zhao jiedi'
In [40]: m[1]
Out[40]: 'zhao'
match.groupdict(default=None)
功能: 将匹配的直接转化为字典
In [41]: m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
In [42]: m.groupdict()
Out[42]: {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
match.start([group])
功能: 获取匹配到的开始位置
In [44]: m = re.search("remove_this", email)
In [45]: email
Out[45]: 'tony@tiremove_thisger.net'
In [46]: m
Out[46]: <_sre.SRE_Match object; span=(7, 18), match='remove_this'>
In [47]: m[0]
Out[47]: 'remove_this'
In [49]: m.start()
Out[49]: 7
In [50]: m.end()
Out[50]: 18
In [52]: email[m.start() : m.end()]
Out[52]: 'remove_this'
In [54]: email[:m.start()] + email[m.end():]
Out[54]: 'tony@tiger.net'
6.3. difflib¶
类似linux环境下的diff命令。
diff样例
In [58]: text1 = '''1. Beautiful is better than ugly.
...: 2. Explicit is better than implicit.
...: 3. Simple is better than complex.
...: 4. Complex is better than complicated.
...: '''.splitlines(keepends=True)
In [59]: text2 = '''1. Beautiful is better than ugly.
...: 2. Explicit is better than implicit.
...: 33. Simple is better than Complex.
...: '''.splitlines(keepends=True)
In [60]: import difflib
In [61]: d = difflib.Differ()
In [62]: result = list(d.compare(text1,text2))
In [63]: result
Out[63]:
[' 1. Beautiful is better than ugly.\n',
' 2. Explicit is better than implicit.\n',
'- 3. Simple is better than complex.\n',
'? ^\n',
'+ 33. Simple is better than Complex.\n',
'? + ^\n',
'- 4. Complex is better than complicated.\n']
6.4. textwrap¶
textwrap提供一些转化和过滤功能。
textwrap.shorten(text, width, **kwargs)
功能: 文本简化
In [66]: import textwrap
In [67]: textwrap.shorten("Hello world!", width=12)
Out[67]: 'Hello world!'
In [68]: textwrap.shorten("Hello world!", width=10)
Out[68]: '[...]'
In [69]: textwrap.shorten("Hello world!", width=11)
Out[69]: 'Hello [...]'
In [70]: textwrap.shorten("Hello world!", width=10,placeholder="...")
Out[70]: 'Hello...'
textwrap.indent(text, prefix, predicate=None)
功能: 文本缩进
In [71]: s = 'hello\n\n \nworld'
In [72]: s
Out[72]: 'hello\n\n \nworld'
In [73]: print(s)
hello
world
In [75]: textwrap.indent(s, ' ')
Out[75]: ' hello\n\n \n world'
In [76]: print(textwrap.indent(s, ' '))
hello
world
使用了indent之后文本会缩进2个字符。
6.5. unicodedata¶
此模块提供对Unicode字符数据库(UCD)的访问,该字符数据库为所有Unicode字符定义字符属性。
样例:
In [83]: import unicodedata
In [84]: unicodedata.lookup('left curly bracket')
Out[84]: '{'
In [85]: unicodedata.name('/')
Out[85]: 'SOLIDUS'
In [86]: unicodedata.decimal('9')
Out[86]: 9
6.6. stringprep¶
6.7. readline¶
readline模块定义了许多函数来方便Python解释器完成和读取/写入历史文件。
6.8. rlcompleter¶
rlcompleter模块通过完成有效的Python标识符和关键字来定义适用于readline模块的完成函数。