第三章 使用字符串
介绍如何使用字符串格式化其他的值,并简单了解一下利用字符串的分割、联接、搜索等方法能做些什么。
3.1 基本字符串操作
所有标准序列操作(索引、分片、乘法、判断成员资格、求长度、取最小值和最大值)对字符串同样适用。
但是,字符串都是不可变的。因此,分片赋值是不合法的。
>>> website = 'http://www.python.org'
>>> website[-3:] = 'com'
TypeError:....
3.2 字符串格式化:精简版
1) 字符串格式化使用字符串格式化操作符即%来实现。(%也可用作模运算(取余)操作符)
具体操作:在%的左侧放置一个字符串(格式化字符串),右侧放置希望格式化的值(可以使用一个值:一个字符串或数字;也可以使用多个值的元组或字典)
>>> format = "Hello, %s. %s enough for ya?" #%s部分为转换说明符(conversion specifier):标记需要插入转换值的位置,s表示值被格式化为字符串—还可有f等
>>> values = ('world', 'Hot')
>>> print format % values
Hello,world. Hot enough for ya?
# 想在格式化字符串里包括%,就必须使用%%,这样Python就不会将百分号误认为是转换说明符了。
想格式化实数(浮点数),可以使用f说明符类型,同时提供所需精度——句点加希望保留小数位数的数字。精度放在类型字符之前。
>>> format = "Pi with three decimals: %.3f"
>>> from math import pi
>>> print format % pi
Pi with three decimals: 3.142
2) string模块提供另一种格式化的方法:模板字符串。
例如:substitute模板方法会用传递进来的关键字参数foo替换字符串中的$foo
>>> from string import Template
>>> s = Template('$x, glorious $x!')
>>> s.substitute(x='slurm')
'slurm, glorious slurm!'
若替换单词一部分,那关键字参数名就必须用{}括起来,从而准确指明结尾:
>>> s = Template("It's ${x}tastic!")
>>> s.substitute(x = 'slurm')
"It's slurmtastic!"
可以用$$插入美元符号
除关键字参数以外,还可使用字典变量提供值或名称对
>>> s = Template('A $thing must never $action.')
>>> d = {}
>>> d['thing'] = 'gentleman'
>>> d['action'] = 'show his socks'
>>> s.substitute(d)
'A gentleman must never show his socks.'
3.3 字符串格式化:完整版
1)格式化操作符的右操作数可以是任何东西,若是元组或映射类型(如字典),那字符串格式化会有所不同。先了解一下元组
若右操作数是元组,则其中每一个元素会单独格式化,每个值都需要一个对应的转换说明符。
需要转换的元组作为转换表达式的一部分存在时,必须要用圆括号将其括起来。
>>> '%s plus %s equals %s' % (1, 1, 2)
'1 plus 1 equals 2'
>>> %s plus %s equals %s' % 1, 1, 2
TypeError:.....
2) 基本的转换说明符——不包含映射键的说明符,包括以下部分,顺序至关重要
(1) %字符:标记转换说明符的开始
(2)转换标志(可选):-左对齐;+在转换值之前要加上正负号;“”(空白字符)表示正数之前保留空格;0表示转换值若位数不够则用0来填充
(3)最小字段宽度(可选):转换后的字符串至少应该具有该值指定的宽度。如果是*,则宽度会从值元组中读出。
(4)点后跟精度值(可选):若转换的是实数,精度值就表示出现在小数点后的位数;如果是字符串,就表示最大字段宽度;如果是*,精度会从元组中读出。
(5) 转换类型:
d, i 带符号的十进制整数
o 不带符号的八进制
u 不带符号的十进制
x 不带符号的十六进制(小写)
X 不带符号的十六进制(大写)
e 科学计数法表示的浮点数(小写)
E 科学计数法表示的浮点数(大写)
f,F 十进制浮点数
g 如果指数大于-4或者小于精度值则和e相同,其他情况和f相同
G 如果指数大于-4或者小于精度值则和E相同,其他情况和F相同
C 单字符(接受整数或单字符字符串)
r 字符串(使用repr转换任意Python对象)
s 字符串(使用str转换任意Python对象)
3.3.1 简单转换:只需要写出转换类型
>>> 'Price of eggs: $%d' % 42
'Price of eggs: $42'
>>> 'Hexadecimal price of eggs: %x' % 42
'Hexadecimal price of eggs: 2a'
>>> from math import pi
>>> 'Pi: %f....' % pi
'Pi: 3.141593....'
>>> 'Very inexact estimate of pi : %i' % pi
'Very inexact estimate of pi : 3'
>>> 'Using str: %s' % 42L
'Using str: 42'
>>> 'Using repr: %r' % 42L
'Using repr:42L'
3.3.2 字段宽度和精度
转换说明符可以包含字段宽度和精度。字段宽度是转换后值所保留的最小字符个数,精度(对数字)是结果中包含的小数位数,或者(对字符串)是转换后的值所能包含的最大字符个数。
这两个参数都是整数(先是字段宽度,后是精度),通过点号分隔。如果只给精度必须包含点号。
>>> '%10f' % pi
' 3.141593'
>>> '%10.2f' %pi
' 3.14'
>>> '%.2f' %pi
'3.14'
>>> '%.5s' % 'Guido van Rossum'
'Guido'
可使用*作为字段宽度或者精度(或两者都用),此时数值会从元组参数中读出
>>> '%.*s' % (5, 'Guido van Rossum')
'Guido'
3.3.3 符号、对齐和0填充
在字段宽度和精度值之前还可以放置一个“标表”(即上文提到的转换标志),可以是:0、加号、减号或空格。
0表示数字将会用0充填。
>>> '%010.2f' % pi #010并不代表字段宽度说明符 为八进制数,只是一个普通的Python数值。此时字段宽度是10,并用0填充空位,而不是说字段宽度为8.
'0000003.14'
减号用来左对齐数值:
>>> '%-10.2f' % pi
'3.14 ' #数字左对齐,空格出现在右边
空格意味着在正数前加上空格。在需要正负数对齐时很有用:
>>> print ('% 5d' % 10) + '\n' + ('% 5d' % -10)
10
-10
加号,表示不管正数还是负数都标示出符号(同在对齐很有用)
>>> print ('%+5d' % 10) + '\n' + ('%+5d' % 10)
+10
-10
#涉及到代码清单3-1 字符串格式化示例
3.4 字符串方法
字符串方法有很多,比列表的多的多。所以此只列一些特别有用的。
字符串未死
一些有用的字符串常量
string.digits: 包含数字0~9的字符串
string.letters:包含所有字母(大写和小写)的字符串
string.lowercase:包含所有小写字母的字符串
string.printable:包含所有可打印字符的字符串
string.punctuation:包含所有标点的字符串
string.uppercase:包含所有大写字母的字符串
3.4.1 find:在一个较长的字符串中查找子字符串,返回子串所在位置的最左端索引。若没有,返回-1
>>> 'With a moo-moo here. and a moo-moo there'.find('moo')
7
>>> title = "Monty Python's Flying Circus"
>>> title.find('Monty')
0
>>> title.find('Python')
6
>>> title.find('Flying')
15
>>> title.find('Zirquss')
-1
可以建立一个垃圾邮件过滤器(前一章用的in)
>>> subject = '$$$ Get rich now!!! $$$'
>>> subject.find('$$$')
0
此方法还可以接受可选的起点值和终点值,如果超出范围也不会报错,但是肯定没有要找的子串,所以会返回-1
>>> subject = '$$$ Get rich now!!! $$$'
>>> subject.find('$$$', 1)
#只提供起点
20
>>> subject.find('!!!', 0, 16)
-1
>>> subject.find('!!!',888)
-1
3.4.2 join:是split方法的逆方法,用来在队列中添加元素 ——分隔符.join(字符列表)
>>> sep = '+'
>>> seq = ['1', '2', '3', '4','5']
>>> sep.join(seq) #连接字符串列表,注意添加的队列元素都必须是字符串,数字会报错
'1+2+3+4+5'
>>> dirs = ' ', 'usr', 'bin', 'env'
>>> '/'.join(dirs)
' /usr/bin/env'
>>> print 'C:' + '\\'.join(dirs)
C:\usr\bin\env
3.4.3 lower:返回字符串的小写字母版
>>> 'Trondheim Hammer Dance'.lower()
'trondheim hammer dance'
可应用于不想区分大小写的代码编写
>>> name = 'Gumby' #用户输入或外部获取的名字,有大写字母。
>>> names = ['gumby', 'smith', 'jones'] #存储的名字是gumby,全部是小写字母
>>> if name.lower() in names : print 'Found if!' #不管用户输入或获取的是什么,都转换为小写字母,以用来和存储比对
...
Found it!
3.4.4 replace:返回某字符串的所有匹配项均被替换之后得到的字符串
>>> 'This is a test'.replace('is', 'eez')
'Theez eez a test'
相当于Word的查找并替换
3.4.5 split:join的逆方法,将字符串分割成序列——字符串.split(分隔符)
>>> '1+2+3+4+5'.split('+')
['1', '2', '3', '4', '5']
>>> 'Using the default'.split()
['Using', 'the', 'default'] #如果不提供任何分隔符,程序会把所有空格作为分隔符
3.4.6 strip:返回去除两侧(不含内部)空格的字符串
>>> ' internal whitespace is kept '.strip()
'internal whitespace is kept'
也可以指定需要去除的字符(两侧的),将它们列为参数就行
>>> '*** SPAM * for * everyone!!! ***'.strip(' *!') #其中在strip括号中的要去除的空格、星号和感叹号的先后位置无影响
'SPAM * for * everyone'
3.4.7 translate:和replace方法一样,但是其只处理单个字符。优势是可以同时进行多个替换。
使用translate转换之前,需要先完成一张转换表—是以某字符替换某字符的对应关系(此表有256个项目)。转换表除自己写外,还可用string模块中的maketrans函数完成。
maketrans函数接受两个参数:两个等长的字符串,表示第一个字符串中的每一个字符都用第二个字符串中相同位置的字符替换。
>>> from string import maketrans
>>> table = maketrans('cs', 'kz') #有两个参数,第一个字符串为‘cs’,第二个字符串为‘kz’,c全部由k代替,s全部由z代替
此时table就是由maketrans函数完成的转换表,可以作为translate方法的参数使用
>>> 'this is an incredible test'.translate(
table) #table 是translate的第一个参数,其还可选用第二个参数——来指定需要删除的字符。
'thiz iz an inkredible tezt'
>>> 'this is an incredible test'.translate(table, ' ')
'thizizaninkredibletezt'
3.5 小结 : 主要介绍了字符串的两种非常重要的使用方式
1 字符串格式化: 求模操作符(%)可用来将其他值转换为包含转换标志的字符串。还能对值进行不同方式的格式化:左右对齐、设定字段宽度及精度值,增加符号(正负号)或者左填充数字0等
2 字符串方法 : 很多。非常有用的如:join、split。有的用的很少如:istitle、capitallize
3.5.1 本章新函数
string.capwords(s[, sep]) 使用split函数分割字符串s(以sep为分隔符),使用capitallize函数将分割得到的各单词首字母大写,并用join函数以sep为分隔符将各单词连接。
string.maketrans(from, to) 创建用于转换的转换表