
2.3 字符串和编码
2.3.1 字符串
字符串也是一种数据类型,甚至有可能是Python里最为常见的数据类型。我们可以通过在引号间包含字符的方式来创建字符串变量。
例2-10 字符串类型赋值

Python里面没有字符这个类型,用长度为1的字符串来表示这个概念,这一点和C语言不同。另外,前面提到单引号和双引号是用来定义字符串的特殊符号,那么问题来了,如果我们想要输出单引号''或者双引号""到屏幕上该怎么办?答案很简单,使用反斜线符号“\”,也叫作转义符。
例2-11 转义字符

不光是双引号""和单引号''可以这样操作,其他的符号也可以通过前置“\”进行转义,所以反斜线又被称为转义符号,表2-1罗列了常用的转义形式。转义符的格式通常是“\”加上某个字母,比如“\ b”是退格、“\ r”表示的是回车,“\ n”表示换行的意思等。
表2-1 常用的字符串转义方式

使用双引号""或者单引号''定义字符串时不可以换行。如果字符串内容必须跨行,可以使用三重引号,在三重引号之间输入任何内容,在最后字符串会照单全收,包括换行、缩进等。
例2-12 三重引号用法

2.3.2 编码
说到字符串,就不得不提一下编码问题。为什么呢?因为无论以什么形式存储在内存中的编码,写入在硬盘上都是二进制,所以编码不对,程序就会出错。常见编码有ASCII编码(美国)、GBK编码(中国)、shift_JIS编码(日本)和Unicode(统一编码)等。
Python 2.x默认的字符编码是ASCII,默认的文件编码也是ASCII。
Python 3.x默认的字符编码是Unicode,默认的文件编码是UTF-8。
ASCII使用一个字节表示一个字符,而Unicode需要2个字节,这样对于英文的文本而言,存储空间就多出了一倍,于是就有了UTF-8(可变长存储,Unicode Transformation Format)。UTF-8简称万国码,可以显示各种语言,如中文、英文、日文、韩文等。UTF-8编码中英文字符只使用1字节表示,中文字符用3字节,其他生僻字使用需要更多的字节存储。如果想要中国的软件可以正常在美国的计算机上运行,就需要下面两种方法:一是让美国的计算机都装上GBK编码;二是让我们的软件编码以UTF-8编码。
第一种方法显然不现实。相对而言,第二种方法要简单一些,但是也只能针对新开发的软件,如果之前开发的软件就是以GBK编码写的,上百万行代码已经写好了,那又该如何处理呢?这些都难不倒聪明的程序员们,他们针对已经用GBK开发的软件项目,利用Unicode的一个包含了全球所有国家语言编码的映射关系的功能,实现了编码转换。所以,目前无论以什么编码存储的数据,只要我们的软件把数据从硬盘上读到内存,转成Unicode就可以正确地显示出来。由于所有的系统、编程语言都默认支持Unicode,所以我们的GBK编码软件放在美国计算机上,加载到内存里面,变成了Unicode,中文就可正常展示了。
总结上面的转码过程:decode("UTF-8")解码-> unicode-> encode("gbk")编码。
小白逆袭:字符集
字符集规定了某个文字对应的二进制数字存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系。
2.3.3 字符串操作
我们已经掌握了很多关于字符串的赋值方法,这是Python数据结构最基本的属性,但仍然有很多复杂的操作特性值得挖掘,下面我们就来详细讨论一下。
1.切片操作
切片操作,顾名思义,就像是给蔬菜切片一样的方式来处理字符串。
例2-13 字符串切片

首先将“Python从小白到大牛”作为内容赋予字符串变量str1,这个变量包括6个英文字母和6个汉字,一共12个字符。然后对变量str1进行切片操作,截取第0个地址至第6个字节之间的内容,就是Python,接着进行下一步切片操作,获取第7至第12个字符,也就是“从小白到大牛”。str1[:1]表示切片的起始位置为空,仅设置了终止位置为6,则和str1[0:6]的结果一样。
注意一点,切片的起始位置是从0开始的,而不是1,可以思考一下原因,后面我们会在列表、字典等章节中介绍。
2.字符串拼接
拼接,就像是小朋友玩的拼字游戏一样,字符串可以用+号连接起来,还可以用*重复输出。
例2-14 字符串拼接和复制

3.字符串运算符
除了拼接字符串时用+号或者*号以外,还有适用于其他功能的运算符,比如用于获取字符串片段的索引运算符[]和切片运算符,以及用于判断元素是否存在的成员运算符in和not in。字符串运算符见表2-2。
表2-2 字符串运算符

先创建两个变量a="人生苦短,"和b="我用python。",然后逐一测试表2-2中的运算符。
例2-15 字符串运算符


注意,其中运算符in和not in返回的是布尔值True和False,这两个运算符经常和循环语句配合使用。
4.字符串格式化
Python也支持格式化字符串输出,基本用法是将一个值插入到一个有字符串格式符%s的内容中,听起来有点绕口,请看下面示例。
例2-16 字符串格式化

这种格式看起来很简单,但是可以演化出非常复杂的显示结构,是一个非常实用的技巧。
5.字符串内建函数
Python自带很多内置函数用于操作字符串,由于篇幅有限,这里只介绍一些非常实用的内置函数。
● find()函数:可以在一个较长的字符串中查找某一个或几个字符,返回字串所在位置的最左端索引,如果什么都没有找到,则返回-1。
例2-17 查找特定字符

● split()函数:根据某个特定字符或者符号来分割字符串,如果不提供分割符,默认空格作为分割符。
例2-18 分割字符串

分割字符串函数除了split()函数以外,还有一个join函数,它与split()的函数用法相反,join()用来连接字符串。
● lower():返回字符串的小写字母表。在不想区分大小写的地方十分有用。
● upper():将所有字母大写,与lower()相对应。
● title():将字符串转换为标题,也就是单词首字母大写,而其余的小写。
例2-19 字符串首字母小写和大写

● replace():返回某字符串的所有匹配项均被替换之后得到的字符串。
例2-20 字符串替换

● index():从序列中查找某个元素的第一个匹配项的索引位置,没有查找到就报错。与find()类似,但是find()只对字符串有效,而find()对序列都有效。
例2-21 字符串索引

● startswith():判定字符串是否是以指定的字符开头,返回布尔值,可以指定检测范围。
例2-22 判断开头字符

与之相对应的是endswith(),用于判断字符串是否以指定的字符结尾,返回布尔值,可以指定检测范围。
最后介绍移除字符串的方法,移除指定字符串有三种方法。strip()用于移除字符串首位指定的字符,默认删除空格;lstrip()用于移除左侧的指定字符;rstrip()用于移除右侧的指定字符。
例2-23 移除指定字符串


内置函数有很多,我们没有必要全部记下来,什么时候有需要,可以去官网上查看其用法就够了。
小白逆袭:查阅内置函数的利器—help()
上面我们介绍很多内置函数,对于初学者,忘记命令用法是很常见的事情。别着急,我们还有不求人的绝招。打开Python解释器,输入help(str)命令,我们会看到非常多的信息,都是Python的内置函数。
>>> help(str)
善用help函数会省去很多查找文档的精力。当然,这种方法不仅可以查看字符串函数,也适用于其他的内置函数。