目录
bytes对象
结论
在Python中的基本数据类型教程中,您学习了如何定义字符串:包含字符数据序列的对象。处理字符数据是编程过程中不可或缺的一部分。至少在某种程度上说,不需要操作字符串的应用非常少见。
以下是您将会在本教程中学习的内容:Python提供了一组丰富的运算符,函数以及方法来处理字符串。完成本教程后,您将会了解如何访问和提取字符串的部分内容,并熟悉可用于字符串操作和修改的方法。
另外两个被用来表示原始字节数据的Python对象bytes和bytearray也会在本教程中向您介绍。
字符串操作
下面的小节中将会重点介绍可用于处理字符串的运算符,方法和函数。
字符串运算符
您已经在Python中的运算符和表达式教程中看到了运算符+和*应用于数值操作数的情况。这两个运算符同样也可以应用于字符串。
+运算符
+运算符可以把字符串连接起来。它返回一个由操作数连接在一起所组成的字符串,如下所示:
*运算符
* 运算符创建字符串的多个副本。如果s是一个字符串,n是一个整数,下面任何一种表达式都可以返回一个由n个s的副本所连接而成的字符串:
s * n
n * s
以下是两种形式的示例:
乘数操作数n必须是一个整数。你也许会认为它必须是一个正整数,但有趣的是,它可以是0或者负数两个字符串连接成一个字符串,在这种情况下结果为空字符串。
如果你要创建一个字符串并通过 “foo” * -8 为其赋值将其初始化成为一个空字符串,所有人都会认为你有点蠢。不过这样做确实是有效的。
in运算符
Python还提供了可以与字符串一同使用的成员运算符。如果第一个操作数被第二个操作数包含,那么in运算符返回True,否则返回Fasle:
此外还有not in运算符,其功能恰好相反:
字符串内置函数
正如您在Python中的基本数据类型教程中所看到的一样,Python提供了许多内置于解释器并始终可用的函数。下面是一些可以作用于字符串的函数:
函数
描述
chr()
将一个整数转化为一个字符
ord()
将一个字符转化为一个整数
len()
返回一个字符串的长度
str()
返回一个对象的字符串表示形式
下面将会对上述方法进行更详细的介绍。
ord(c)
对于给定字符返回一个整数值
从最基础的层面来说,计算机将所有的信息用数字形式存储。为了表示字符数据,需要一种将每一个字符映射为对应数字的转换方案。
目前普遍使用的方案中,ASCII是最简单的。它涵盖了您可能最习惯使用的普通拉丁字符。 对于这些字符,ord(c)返回字符c的ASCII编码值:
ASCII就其本身而言还不错。但是世界上正在使用着许多不同的语言,数字媒体中出现了数不清的符号和字形。可能需要在计算机代码中表示的完整字符集远远超过您通常看到的普通拉丁字母,数字和符号。
Unicode是一个雄心勃勃的标准,它试图在每个可能的平台上,对各种可能的语言,为每个可能的字符提供数字编码。 Python 3广泛支持Unicode,包括允许字符串中使用Unicode字符。
了解更多信息:请参考Python文档中Python的Unicode支持。
当您处于常用字符域时,ASCII和Unicode之间几乎没有实际区别。 但是ord()函数也可以返回Unicode字符的编码值:
chr(c)
对于给定整数返回一个字符值
chr()与ord()相反。给定数值n,chr(n)返回与n相对应的字符的字符串。
chr()同样也可以处理Unicode字符:
len(s)
返回一个字符串的长度
len()返回s中字符的数目:
str(obj)
返回一个对象的字符串表示
事实上,Python中的任何对象都可以呈现为字符串。 str(obj)返回对象obj的字符串表示形式:
字符串索引
通常在编程语言中,可以使用数字索引或键值直接访问有序数据集中的各个项目。 此过程称为索引。
在Python中,字符串是字符数据的有序序列,因此可以以这种方式进行索引。 通过指定字符串名后方括号([])中的数字来访问字符串中的单个字符。
Python中的字符串索引从零开始:字符串中的第一个字符具有索引0,下一个字符具有索引1,依此类推。 最后一个字符的索引将是字符串的长度减去1。
例如,字符串”foobar”的索引示意图如下所示:
字符串索引
可以通过索引访问各个字符,如下所示:
尝试超出字符串末尾的索引会导致错误:
字符串索引也可以用负数指定,在这种情况下,索引在字符串中由后向前开始:-1指向最后一个字符,-2指向倒数第二个字符,依此类推。以下是显示字符串中正负索引的相同图表”foobar”:
正数和负数索引
下面是一些负数索引的例子:
尝试使用超出字符串开头的负数进行索引会导致错误:
对于任意非空字符串s,s[len(s)-1]以及s[-1]都返回的最后一个字符。对于空字符串,任何索引都是没有意义的。
字符串切片
Python中还允许一种能够从字符串中提取子字符串索引语法形式,该操作称为字符串切片。如果s是一个字符串,则形如s[m:n]的表达式返回s中以m位置开头,以n位置结束(不包含该位置)的部分:
请记住:字符串索引从零开始。字符串中的第一个字符的索引是0。在标准的索引以及切片中这都是适用的。
此外,第二个索引指定的是结果中未被包含的第一个字符 ——上例中的字符‘r”(s[5])。这可能看起来有点不直观,但它产生这样的结果是有意义的:表达式s[m:n]将返回一个长度为n – m字符的子字符串,在本例中为5 – 2 = 3。
如果您省略第一个索引,则切片从字符串的头部开始。因此,s[:m]和s[0:m]是等效的:
类似的,如果省略第二个索引如s[n:],则切片从第一个索引延续到字符串的末尾。这是对繁琐的s[n:len(s)]的一种更好的,更简洁的替代方案:
对于任何字符串s和任何整数n(0 ≤ n ≤ len(s)),s[:n] + s[n:]将等于s:
省略两个索引将完整地返回原始字符串。然而它不是原始字符串的副本两个字符串连接成一个字符串,它是对原始字符串的引用:
如果切片中的第一个索引大于或等于第二个索引,则Python返回一个空字符串。如果你正在寻找一种另类的生成空字符串的方式,那么这是一种方法:
负数索引也可以与切片一起使用。-1表示最后一个字符,-2倒数第二个,依此类推,就像基本的索引一样。下图显示了如何使用正数索引和负数索引从字符串”foobar”中切割子字符串”oob”:
正负索引在字符串切片中的使用
下面是对应的Python代码:
在字符串切片过程中指定步幅
还有一种切片语法的变形可以进行介绍。再添加一个参数:第三个参数指明步幅(也叫做步长),表明在切片中检索字符时每次跳过多少个字符。
例如,对于字符串”foobar”,切片0:6:2以第一个字符开头,以最后一个字符(整个字符串)结束,并且每次跳过第二个字符。如下图所示:
带有步幅的字符串索引
类似的,1:6:2指定以第二个字符(索引1)开头并以最后一个字符结束的切片,并且步幅值再次为2导致每次都有一个字符被跳过:
另一个带有步幅的字符串索引
说明的REPL代码如下:
对于任何切片,可以省略第一个和第二个索引,并分别默认为第一个和最后一个字符:
您也可以指定负数步幅值,在这种情况下,Python会从后向前逐步处理字符串。在这种情况下,起始/第一个索引应该大于结束/第二个索引:
在上面的示例中,5:0:-2表示“从最后一个字符开始,每次后退2步,直到(但不包括)第一个字符”。
当您后退时,如果省略第一个和第二个索引,则以直观的方式反转默认值:第一个索引默认为字符串的结尾,第二个索引默认为开头。下面是一个例子:
下面是反转字符串的常见范例:
向字符串中插入变量
在Python 3.6中,引入了一种新的字符串格式化机制。此功能正式命名为Formatted String Literal,但更常见的是其昵称f-string。
f-strings提供的格式化功能非常广泛,这里不会详细介绍。如果您想了解更多信息,可以查看Real Python的文章Python 3’s f-Strings: An Improved String Formatting Syntax (Guide)。本系列后面还有一个关于格式化输出的教程,该教程对f-string进行了深入研究。
您可以立即开始使用一个简单的f-string串的功能是变量插入。您可以直接在f-string文字中指定变量名称,Python将使用相应的值替换名称。
例如,假设您要显示算术计算的结果。您可以使用简单的print()语句执行此操作,使用逗号分隔数值和字符串文字:
但这很麻烦。使用f-string可以完成同样的事情:
使用f-string重新实现,上面的示例看起来更清晰:
Python的三种引用机制中的任何一种都可用于定义f-string:
修改字符串
简而言之,你做不到。字符串是Python认为不可变的数据类型之一,意味着无法更改。实际上,到目前为止您看到的所有数据类型都是不可变的。(Python确实提供了可变的数据类型,您很快就会看到。)
像这样的语句会导致错误:
事实上,确实没有太多修改字符串的必要。通过在特定位置生成具有所需更改的原始字符串的副本,您通常可以轻松地完成所需的操作。在Python中有很多方法可以做到这一点。如下一种可能的方法:
还有一个内置的字符串方法来完成此任务:
有关内置字符串方法的更多信息,请继续阅读!
字符串内置方法
您在Python中的变量教程中了解到Python是一种高度面向对象的语言。Python程序中的每个数据项都是一个对象。
此外您也熟悉了函数:可调用以执行特定任务的可调用过程。
方法类似于函数。方法是与对象紧密关联的特殊类型的可调用过程。与函数一样,方法可以被调用从而执行不同的任务,但是它是在特定对象上调用的并且在执行期间需要了解其目标对象。
在对象上调用方法的语法如下:
这将调用对象obj上的方法.foo()。指定传递给方法的参数(如果有)。
稍后在面向对象编程的讨论中,您将探索有关定义和调用方法的更多信息。目前,我们的目标是介绍Python支持的一些常用的用于对字符串对象进行操作的内置方法。
在以下方法定义中,方括号([])中指定的参数是可选的。
大小写转换
本组方法对目标字符串执行大小写转换。
s.capitalize()
目标字符串首字母大写
s.capitalize()返回一个s的副本,第一个字符转换为大写,所有其他字符转换为小写:
非字母字符不变:
s.lower()
将字母字符转换为小写
s.lower()返回s中所有字母字符转换为小写的副本:
s.swapcase()
转换字母字符大小写
s.swapcase()返回一个s中大写字母字符转换为小写,小写字母转化为大写的副本:
s.title()
将目标字符串转化为单词首字母大写
s.title()返回s的一个副本,其中每个单词的第一个字母转换为大写,其余字母为小写:
该方法使用相当简单的算法。它并不试图区分重要和不重要的单词,而且它不能优雅地处理撇号,所有格或首字母缩略词:
s.upper()
将字母字符转化为大写
s.upper()返回s中所有字母字符转换为大写的副本:
查找和替换
这些方法提供了在目标字符串中搜索指定子字符串的各种方式。
该组中的每个方法都支持可选的和参数。这些参数在字符串切片时被解释:方法的操作仅限于目标字符串中从位置字符开始到(不包括)位置字符的部分。如果被指定了但没有,则该方法应用于目标字符串中从开始直到字符串的末尾的部分。
s.count([, [, ]])
计算目标字符串中子字符串的出现次数
s.count()返回字符串s中非重叠子串出现的次数:
计数被限制在由和所指定的子串内,如果参数被设定的话:
s.endswith([, [, ]])
判断目标字符串是否以给定子字符串结尾
如果s以指定的结尾,s.endswith()返回True,否则返回False:
判断被限制在由和所指定的子串内,如果参数被设定的话:
s.find([, [, ]]
在目标字符串中搜索给定的子字符串
s.find()返回在s中找到子字符串的最小索引:
如果指定的子串没有找到,该方法返回-1:
检索被限制在由和所指定的子串内,如果参数被设定的话:
s.index([, [, ]])
在目标字符串中搜索给定的子字符串
这个方法与.find()功能相同,只是在查找不到时会产生一个异常而非返回-1:
s.rfind([, [, ]])
从末尾开始搜索目标字符串中的给定子字符串
s.rfind()返回在s中找到子字符串的最大索引:
和.find()一样,如果指定的子串没有找到,该方法返回-1:
检索被限制在由和所指定的子串内,如果参数被设定的话:
s.rindex([, [, ]])
从末尾开始搜索目标字符串中的给定子字符串
这个方法与.rfind()功能相同,只是在查找不到时会产生一个异常而非返回-1:
s.startswith(
[, [, ]])
判断目标字符串是否以给定子字符串开头
如果s以指定的开头,s.startswith()返回True,否则返回False:
判断被限制在由和所指定的子串内,如果参数被设定的话:
字符分类
此组方法根据字符串包含的字符对字符串进行分类。
s.isalnum()
确定目标字符串是否由字母数字字符组成
如果s是非空的且其所有字符都是字母或数字,s.isalnum()返回True,否则返回False:
s.isalpha()
判断目标字符串是否由字母字符组成
如果s是非空的并且其所有字符都是字母,s.isalpha()返回True,否则返回False:
s.isdigit()
判断目标字符串是否由数字字符组成
如果s是非空的并且其所有字符都是数字,s.digit()返回True,否则返回False:
s.isidentifier()
判断目标字符串是否是有效的Python标识符
如果s根据语言定义是有效的Python标识符,s.isidentifier()返回True,否则返回False:
注意:与Python关键字匹配的字符串.isidentifier()将返回True,即使它实际上不是有效的标识符:
您可以调用iskeyword()函数测试字符串是否与Python关键字匹配,该函数包含在名为keyword的模块中。一种可能的方法如下所示:
如果你真的想确保一个字符串可以作为一个有效的Python标识符,你应该检查.isidentifier()是否为True以及iskeyword()是否为False。
请参阅Python Modules and Packages—An Introduction阅读有关Python模块的更多信息。
s.islower()
判断目标字符串的字母字符是否为小写
如果s是非空的并且它包含的所有字母字符都是小写的,s.islower()则返回True,否则返回False。忽略非字母字符:
s.isprintable()
判断目标字符串是否完全由可打印字符组成
如果s为空或其包含的所有字母字符都是可打印的,s.isprintable()返回True。如果s包含至少一个不可打印的字符,则返回False。忽略非字母字符:
注意:如果s是空字符串,这是唯一个返回True的.isxxxx()方法。所有其它方法都对空字符串返回False。
英文原文:
译者:搞一个大新闻