目录
下一小节:replace、split、strip、translate等
3.4 字符串方法
字符串从string模块中“继承”了很多方法,早期的python版本,这些方法都是作为函数出现的。
但是字符串未死
尽管字符串方法完全来源于string模块,但是这个模块还包括一些不能作为字符串方法使用的常量和函数。Maketrans函数就是其中之一,后面会将它和translate方法一起介绍。下面介绍一些有用的字符串常量。
(1)string.digits:包含数字0~9的字符串('0123456789')
(2)string.letters:包含所有字母(大写或小写)的字符串
(3)string.lowercase:包含所有小写字母的字符串
(4)string.printable:包含所有可打印字符的字符串('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c')
(5)string.punctuation:包含所有标点的字符串。('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
(6)string.uppercase:包含所有大写字母的字符串
字母字符串常量(例如string.letters)与地区有关(也就是说,其具体值取决于python所配置的语言,python3.0中string.letters和相关内容都会被移除,如果需要则应该使用string.ascii_letters常量代替)。
>>> import string
>>> print(string.letters)
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
以下是python3的情况
>>> import string
>>> string.letters #python3 string.letters 报错
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
string.letters
AttributeError: module 'string' has no attribute 'letters'
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
Ps:同样的还有string.ascii_lowercase,string.ascii_uppercase
3.4.1 find方法
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
在第2章初识了成员资格,我们在subject中使用了’$$$’表达式建立了一个垃圾邮件过滤器。也可以使用find方法(python2.3以前的版本中也可用,但是in操作符只能用来查找字符串中的单个字符?):
>>> subject = '$$$ Get rich now!!! $$$'
>>> subject.find('$$$')
0
>>> '$$$' in subject
True
注意:字符串中的find方法并不返回布尔值。如果返回的是0,则证明在索引0位置找到了子串。
这个方法还可以接收可选的起始点和结束点参数:
>>> subject = '$$$ Get rich now!!! $$$'
>>> subject.find('$$$')
0
>>> subject.find('$$$', 1) #只提供起始点
20
>>> subject.find('!!!')
16
>>> subject.find('!!!', 0, 16) #提供起始点和结束点
-1
注意,由起始和终止值指定的范围(第二个和第三个参数)包含第一个索引,但不包含第二个索引。这在python中是个惯例。
附录B:rfind、index、rindex、count、startswitch、endswitch
3.4.2 join
join方法是非常重要的字符串方法,他是split方法的逆方法,用来连接序列中的元素
>>> seq = [1, 2, 3, 4, 5]
>>> sep = '+'
>>> sep.join(seq) #连接数字列表
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, int found
>>> 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
>>> print 'C:' + '\'.join(dirs)
File "<stdin>", line 1
print 'C:' + '\'.join(dirs)
^
SyntaxError: EOL while scanning string literal
可以看到,需要被连接的序列元素都必须是字符串。注意最后两个例子中使用了目录的列表,而在格式化时,根据UNIX和DOS/Windows的约定,使用了不同的分隔符号(在DOS版中还增加了驱动名)
请参见:split
3.4.3 lower
(前面有模板字符串import string中string.lowercase,3.0是ascii_lowercase)
>>> string.letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz' #回顾一下
lower方法返回字符串的小写字母版
>>> 'Trondheim Hammer Dance'.lower()
'trondheim hammer dance'
如果想要编写“不区分大小写”的代码的话,那么这个方法就派上用场了---代码会自动忽略大小写状态。例如,如果想在列表中查找一个用户名是否存在:列表包含字符串gumby,而用户输入的是‘Gumby’,就找不到了。
>>> if 'Gumby' in ['gumby', 'smith', 'jones']: print 'Found it!'
...
>>>
如果存储的是‘Gumby’而用户输入的是’gumby’甚至是‘GUMBY’,结果也是一样,解决方法就是在存储和搜索时将所有名字都转换为小写。如下:
>>> name = 'Gumby'
>>> names = ['gumby', 'smith', 'jones']
>>> if name.lower() in names: print 'Found it!'
...
Found it!
>>> if 'Gumby'.lower() in ['gumby', 'smith', 'jones']: print 'Found it!' #直接一条语句
...
Found it!
请参见:translate
附录B:islower、capitalize、swapcase、title、istitle、upper、isupper
标题转换
和lower方法相关的是title方法(参见附录B),他会将字符串转换为标题---也就是所有单词的首字母大写,而其他字母小写。但是它使用的单词划分方法可能会得到并不自然的结果:
>>> "that's all folks".title()
"That'S All Folks"
再介绍另外一个string模块的capwords函数:
>>> import string
>>> string.capwords("that's all folks")
"That's All Folks"
当然,如果要得到正确首字母大写的标题(这要根据你的风格而定,可能要小写冠词、连词及5个字母以下的介词等),那么还是得自己把握。