python3: 字符串和文本(3)
11. 删除字符串中不需要的字符
strip()
方法能用于删除开始或结尾的字符;
lstrip()
和 rstrip()
分别从左和从右执行删除操作
>>> s = ' hello world \n' >>> s = s.strip() >>> s 'hello world' >>>
如果你想处理中间的空格,那么你需要求助其他技术。比如使用 replace()
方法或者是用正则表达式re.sub()替换。示例如下:
>>> s.replace(' ', '') 'helloworld' >>> import re >>> re.sub('\s+', ' ', s) 'hello world' >>>
\s+: 匹配空格1次~多次
对于更高阶的strip,你可能需要使用 translate()
方法
12. 审查清理文本字符串
s = 'pýtĥöñ\fis\tawesome\r\n' >>> remap = { ... ord('\t') : ' ', ... ord('\f') : ' ', ... ord('\r') : None # Deleted ... } >>> a = s.translate(remap) >>> a 'pýtĥöñ is awesome\n'
你可以以这个表格为基础进一步构建更大的表格。比如,让我们删除所有的和音符
>>> import unicodedata >>> import sys >>> cmb_chrs = dict.fromkeys(c for c in range(sys.maxunicode) ... if unicodedata.combining(chr(c))) ... >>> b = unicodedata.normalize('NFD', a) >>> b 'pýtĥöñ is awesome\n' >>> b.translate(cmb_chrs) 'python is awesome\n' >>>
通过使用 dict.fromkeys()
方法构造一个字典,每个Unicode和音符作为键,对应的值全部为 None
。
13. 字符串对齐[format]
对于基本的字符串对齐操作,可以使用字符串的 ljust()
, rjust()
和 center()
方法
>>> text = 'Hello World' >>> text.ljust(20) 'Hello World ' >>> text.rjust(20) ' Hello World' >>> text.center(20) ' Hello World ' >>>
所有这些方法都能接受一个可选的填充字符。比如:
>>> text.rjust(20,'=') '=========Hello World' >>> text.center(20,'*') '****Hello World*****' >>>
函数 format()
同样可以用来很容易的对齐字符串。 你要做的就是使用 <,>
或者 ^
字符后面紧跟一个指定的宽度。比如:
>>> format(text, '>20') ' Hello World' >>> format(text, '<20') 'Hello World ' >>> format(text, '^20') ' Hello World ' >>>
如果你想指定一个非空格的填充字符,将它写到对齐字符的前面即可:
>>> format(text, '=>20s') '=========Hello World' >>> format(text, '*^20s') '****Hello World*****' >>>
当格式化多个值的时候,这些格式代码也可以被用在 format()
方法中。比如:
>>> x = 1.2345 >>> format(x, '>10') ' 1.2345' >>> format(x, '^10.2f') ' 1.23 ' >>>
14. 合并拼接字符串(join, +)
如果你想要合并的字符串是在一个序列或者 iterable
中,那么最快的方式就是使用 join()
方法。比如:
>>> parts = ['Is', 'Chicago', 'Not', 'Chicago?'] >>> ' '.join(parts) 'Is Chicago Not Chicago?' >>> ','.join(parts) 'Is,Chicago,Not,Chicago?' >>> ''.join(parts) 'IsChicagoNotChicago?' >>>
合并少数几个字符串,使用加号(+)通常已经足够了:
>>> a = 'Is Chicago' >>> b = 'Not Chicago?' >>> a + ' ' + b 'Is Chicago Not Chicago?' >>>
加号(+)操作符在作为一些复杂字符串格式化的替代方案的时候通常也工作的很好,比如:
>>> print('{} {}'.format(a,b)) Is Chicago Not Chicago? >>> print(a + ' ' + b) Is Chicago Not Chicago? >>>
如果你想在源码中将两个字面字符串合并起来,你只需要简单的将它们放到一起,不需要用加号(+)。比如:
>>> a = 'Hello' 'World' >>> a 'HelloWorld' >>>
最重要的需要引起注意的是,当我们使用加号(+)操作符去连接大量的字符串的时候是非常低效率的, 因为加号连接会引起内存复制以及垃圾回收操作。 特别的,你永远都不应像下面这样写字符串连接代码:
s = '' for p in parts: s += p
一个相对比较聪明的技巧是利用生成器表达式(参考1.19小节)转换数据为字符串的同时合并字符串,比如:
>>> data = ['ACME', 50, 91.1] >>> ','.join(str(d) for d in data) 'ACME,50,91.1' >>>
同样还得注意不必要的字符串连接操作。有时候程序员在没有必要做连接操作的时候仍然多此一举。比如在打印的时候:
print(a + ':' + b + ':' + c) # Ugly print(':'.join([a, b, c])) # Still ugly print(a, b, c, sep=':') # Better
15. 字符串中插入变量
>>> s = '{name} has {n} messages.' >>> s.format(name='Guido', n=37) 'Guido has 37 messages.' >>>
如果要被替换的变量能在变量域中找到, 那么你可以结合使用 format_map()
和 vars()
。就像下面这样
>>> name = 'Guido' >>> n = 37 >>> s.format_map(vars()) 'Guido has 37 messages.' >>>
vars()
还有一个有意思的特性就是它也适用于对象实例。比如:
>>> class Info: ... def __init__(self, name, n): ... self.name = name ... self.n = n ... >>> a = Info('Guido',37) >>> s.format_map(vars(a)) 'Guido has 37 messages.' >>>
format
和 format_map()
的一个缺陷就是它们并不能很好的处理变量缺失的情况,比如:
>>> s.format(name='Guido') Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'n' >>>
一种避免这种错误的方法是另外定义一个含有 __missing__()
方法的字典对象,就像下面这样:
class safesub(dict): """防止key找不到""" def __missing__(self, key): return '{' + key + '}'
现在你可以利用这个类包装输入后传递给 format_map()
>>> del n # Make sure n is undefined >>> s.format_map(safesub(vars())) 'Guido has {n} messages.' >>>
如果你发现自己在代码中频繁的执行这些步骤,你可以将变量替换步骤用一个工具函数封装起来。就像下面这样:
import sys def sub(text): return text.format_map(safesub(sys._getframe(1).f_locals))
现在你可以像下面这样写了:
>>> name = 'Guido' >>> n = 37 >>> print(sub('Hello {name}')) Hello Guido >>> print(sub('You have {n} messages.')) You have 37 messages. >>> print(sub('Your favorite color is {color}')) Your favorite color is {color} >>>
可以使用字符串模版
>>> import string >>> s = string.Template('$name has $n messages.') >>> s.substitute(vars()) 'Guido has 37 messages.' >>>