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模块的完成函数。