Python 与字符串相关的方法可以分为以下两类:
- 通用操作:可用于多种类型,以内置函数或表达式的方式提供。如
len(s)
s[0]
x in s
等。 - 只用于字符串类型的操作:以方法调用形式提供,如
str.split()
str.lower()
等。
下面,我们就来分类总结和学习一下 Python 中与字符串相关的操作。
一. 通用操作
在 Python 中,由于序列的下标和切片操作、计算长度和判断元素是否存在于序列中都是很通用的操作,不仅适用于字符串,也同样使用于列表、元组等其它序列。
因此,对于上述的通用操作,Python 使用内置函数和表达式的方式予以实现。这样,相同的方式可以应用于列表、元组等其它序列。
>> s = "hello python"
>> len(s)
12
>> 'python' in s
True
>> 'java' not in s
True
上述操作也同样适用于列表:
>> L = list(range(5))
>> len(L)
5
>> 3 in L
True
>> '3' not in L
True
Python 对共性的操作提炼成了通用的函数或表达式,而不是为每种类型都提供相应的方法。
二.与大小写有关的方法
Python 字符串与大小写有关的方法总结如下:
方法 | 释义 |
---|---|
upper |
将 str 转换为大写。 |
lower |
将 str 转换为小写。 |
isupper |
判断 str 是否都为大写。 |
islower |
判断 str 是否都为小写。 |
swapcase |
将 str 中的大写转换为小写,小写转换为大写。 |
capitalize |
将首字母转换为大写。 |
istitle |
判断 str 中是否每个单词的首字母都大写。 |
示例:
>> 'mia li'.upper()
'MIA LI'
>> 'MIA LI'.lower()
'mia li'
>> 'Mia Li'.isupper()
False
>> 'mia li'.islower()
True
>> 'Mia Li'.swapcase()
'mIA lI'
>> 'hello python'.capitalize()
'Hello python'
>> 'Mia Li'.title()
'Mia Li'
>> 'Mia Li'.istitle()
True
由于 Python 中的字符串时不可变序列,因此这里的方法并没有改变原来的字符串,而是返回了一个新的字符串。
将字符串转换为大写或小写是很实用的方法。比如下面的例子:程序等待用户输入,在输入 yes
YES
Yes
等等时,执行某项操作,否则退出程序。
yes_or_no = input('Please input yes or no: ')
if yes_or_no.lower() == 'yes':
print('do some operations')
else:
print('exit')
三. 判断类方法
Python 的字符串有很多以 is
开头的方法,如上文提到的 isupper
islower
istitle
;这些都是判断类的方法,他们不会产生新的字符串,并且总是返回 True
或 False
。
方法 | 释义 |
---|---|
isalpha |
在 str 只包含字母且非空时返回 True ,否则返回 False 。 |
isalnum |
在 str 只包含字母和数字且非空时返回 True ,否则返回 False 。 |
issapce |
在 str 只包含空格、制表符、换行符并且非空时返回 True ,否则返回 False 。 |
isdecimal |
在 str 只包含数字字符且非空时返回 True ,否则返回 False 。 |
startswith |
判断方法的参数是否为字符串的前缀。 |
endswith |
判断方法的参数是否为字符串的后缀。 |
示例:
>> 'python'.isalpha()
True
>> 'python3'.isalpha()
False
>> 'python3'.isalnum()
True
>> 'python 3'.isalnum()
False
>> 'python 3'.isspace()
False
>> ' \n\t'.isspace()
True
>> 'python 3.6'.isdecimal()
False
>> '3.6'.isdecimal()
False
>> '36'.isdecimal()
True
>> 'python 3.6'.startswith('python')
True
>> 'python 3.6'.startswith('python 3')
True
>> 'python 3.6'.endswith('3.6')
True
下面,我们再看一个更加实用的例子。系统目录 /var/log
下面有各种应用产生的各种各样的日志文件,我们需要找到所有正在记录的 log
文件:
>>> [ item for item in os.listdir('/var/log') if item.endswith('log')]
['dpkg.log', 'lastlog', 'faillog', 'fontconfig.log', 'auth.log', 'alternatives.log', 'bootstrap.log', 'kern.log', 'syslog', 'mail.log']
可能更常见的场景是获取某个应用的所有日志文件,假设这里我们需要获取所有的 syslog
文件,并计算所有 syslog
文件占用的磁盘大小:
>>> syslogs = [ item for item in os.listdir('/var/log') if item.startswith('syslog')]
>>> syslogs
['syslog.5.gz', 'syslog.4.gz', 'syslog.3.gz', 'syslog.2.gz', 'syslog', 'syslog.6.gz', 'syslog.1', 'syslog.7.gz']
>>> sum(os.path.getsize(os.path.join('/var/log', item)) for item in syslogs)
770073
四. 查找类方法
查找类方法用来查找子串在字符串中出现的位置,而它们之间的区别则是查找的方向不同,或者处理异常的方式不同。下面是 Python 中查找类方法的总结:
方法 | 释义 |
---|---|
find |
查找子串出现在字符串中的位置,未找到时返回 -1 |
rfind |
与 find 类似,区别在于 rfind 是从右向左查找 |
index |
与 find 类似,区别在于 index 在未找到时抛出 ValueError 异常 |
rindex |
与 index 类似,区别在于 rindex 是从右向左查找 |
示例:
>> s = "Beautiful is better than ugly.Explicit is better than implicit."
>> s.find('is better than')
10
>> s.rfind('is better than')
39
>> s.find('python')
-1
此外,在查找子字符串出现的位置时,还可以指定从哪个位置开始找:
>> s.find('is better than', 11)
39
index
查找子串:
>> s.index('is better than')
10
>> s.rindex('is better than')
39
>> s.index('is better than', 11)
39
>> s.index('python')
ValueError: substring not found
另外,提醒一下上述方法都是用来查找子串出现在字符串中的位置,如果是判断一个字符串是否存在于另一个字符串中,请使用上文提到的操作符 in / not in
。
五. 字符串操作方法
文章的最后,我们来介绍几个非常重要的字符串操作方法,如下:
方法 | 释义 |
---|---|
join |
用以连接字符串列表(可迭代对象),返回一个新的字符串 |
split |
与 join 作用相反,用以将字符串拆分成字符串列表 |
strip lstrip rstrip
|
分别用于对字符串的两边、左边、右边进行裁剪 |
replace |
将字符串中的子串替换为指定字符串 |
join
调用 join
函数的字符串将作为 “分隔符” 插入到待连接字符串的中间:
>> L = ['p', 'y', 't', 'h', 'o', 'n']
>> ''.join(L)
'python'
>> '#'.join(L)
'p#y#t#h#o#n'
join
函数其实设计得非常通用,接收的参数只要是可迭代对象即可:
比如,我们需要将文件中的内容拼接成一个字符串,只需要将文件句柄传递给 join
方法即可,因为文件对象本身就是一个可迭代对象:
with open('example.txt') as f:
s = '# '.join(f)
print(s)
运行结果:
文件内容如下:
这里需要提醒一下,print
函数在打印多项内容时,可以通过 sep
指定分隔符:
>> print('mia', 'x', 2027, 2013)
mia x 2027 2013
>> print('mia', 'x', 2027, 2013, sep=':')
mia:x:2027:2013
因此,可不要惯性思维,使用 join
将字符串列表再拼接一遍。。而且,由于这里的内容不仅仅是字符串,还有两个整数,因此使用 join
拼接打印还会报错哦:
>> print(':'.join(['mia', 'x', 2027, 2013]))
TypeError: sequence item 2: expected str instance, int found
split
上文我们了解到 join
方法用于将字符串列表(可迭代对象)拼接成一个更大的字符串,而 split
方法则与 join
的作用相反,用以将一个字符串拆分成字符串列表:
>> 'nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin'.split(':')
['nobody',
'x',
'65534',
'65534',
'nobody',
'/nonexistent',
'/usr/sbin/nologin']
用以拆分字符串的 “分隔符” 也可以省略,省略时使用空白字符串(空格、换行符、制表符)进行拆分:
>> with open('example.txt') as f:
s = f.read(65)
>> print(s)
Beautiful is better than ugly.
Explicit is better than implicit.
>> s.split()
['Beautiful',
'is',
'better',
'than',
'ugly.',
'Explicit',
'is',
'better',
'than',
'implicit.']
strip lstrip rstrip
strip
lstrip
rstrip
用于对字符串进行裁剪,除了裁剪的范围不一样之外,没有任何区别。split
方法常见的用法即去除字符串两端的空白:
>> s = ' \t\v\r\n Python 3.7 \t\v\r\n '
>> s.strip()
'Python 3.7'
>> s.lstrip()
'Python 3.7 \t\x0b\r\n '
>> s.rstrip()
' \t\x0b\r\n Python 3.7'
此外,也可以给 strip
传递参数,参数中的所有字符都将被裁剪:
下面是一个示例:
>> s = '##Hello, Python##'
>> s.strip('#')
'Hello, Python'
>> s.strip('###')
'Hello, Python'
>> s.strip('H#n')
'ello, Pytho'
>> s.strip('nH#')
'ello, Pytho'
注:传递给
strip
方法的参数是需要被裁剪的字符集合,因为是集合,所以字符的顺序并不重要,重复的字符也没有任何效果。
replace
replace
方法非常简单,顾名思义就是将字符串中的子串替换成指定的字符串:
>> s = '##Hello, Python##'
>> s.replace('##', '***')
'***Hello, Python***'