一、前言
大家好,我是更新看缘分的李鹏李先生。
本次课程主讲 Python 中的字符串,闲话少说,直接开始。
本文约3500字,阅读需15分钟左右,祝大家阅读愉快。
二、字符串
在学习今天的内容之前,我们要首先了解一下到底什么是字符串。
我们平常说的话,和别人沟通交流的语言其实就是字符串。
只不过在 Python 当中,字符串演变成了一种数据类型,但是我们虽然知道了字符串演变成了一种数据类型,
可是这种类型在计算机当中是如何来使用的呢?我想在计算机中使用中文行不行呢?
接下来我们首先来探究一下 Python 中编码格式的问题。
2.1 ASCII 编码
首先声明,计算机底层当中不能接收中文,甚至连文本都无法处理。
必须要转换成数字来进行表示,也就是我们常说的字节。
需要注意:
- 1 字节(byte) = 8 比特(bit)
- 一个字节能表示的最大的整数就是255(即二进制11111111)
- 两个字节可以表示的最大整数是65 535
- 四个字节可以表示的最大整数是4 294 967 295
最开始的计算机,就只保存了127个字符在计算机里面,其中包含了数字、字母、特殊符号等等。
而这个表则统称为 ASCII编码。
其中我们需要注意的就是我们需要记住的就只有其中三个。
十进制表示 | 内容 | 含义 |
---|---|---|
48 | 0 | 数字 0 |
65 | A | 字母 A (大写) |
97 | a | 字母 a (小写) |
通过记住这三个内容,我们可以分别推出 0 ~ 9
、A ~ Z
、a ~ z
的 ASCII 编码数字。
2.2 Unicode
既然有了 ASCII 编码,那是不是就完事大吉了呢?
当然不是,如果中国有自己的编码表(GB2312编码),日本也有自己的编码表(Shift_JIS),韩国也有韩文编码表(Euc-kr),那岂不是天下大乱?
你在中国写的东西,到日本,到韩国就直接变成了一堆乱码,那我相信,我们的工作生活将会受到极大的影响。
那么这时候我们该怎么办呢?
这时候国际标准化组织(ISO)和多语言软件制造商组成的统一码联盟站了出来,他们联合其他机构进行了统一化的工作,而统一化的结果就是我们熟知的 Unicode 编码。
通过 Unicode,就可以实现在不同国家之间,可以将文字和语言相通啦。
但是部分国家使用的都是汉字,而某些国家日常通信使用的都是英文,这里面其实有很大的差别。
要知道汉字已经超出了ASCII编码的范围,并且大部分需要使用两个字节来表示,有些甚至需要四个四节,而英文只需要一个字节即可。
字母
A
用ASCII编码是十进制的65
,二进制的01000001
;字符
0
用ASCII编码是十进制的48
,二进制的00110000
,注意字符'0'
和整数0
是不同的;汉字
中
已经超出了ASCII编码的范围,用Unicode编码是十进制的20013
,二进制的01001110 00101101
。
那我们是不是就应该在书写中文相关的内容时,需要使用 Unicode 编码,
书写通篇是英文或者数字的时候,应该优先使用 ASCII 编码。
这时候我们就要讲到一个新的标准,UTF-8啦。
2.3 UTF-8
由于为了要节省空间,应该使用ASCII 编码的内容就不应该去使用 Unicode 编码。
A 的 ASCII 编码:01000001
A 的 Unicode 编码:00000000 01000001
那计算机怎么区分什么时候应该使用Unicode 编码,什么时候使用 ASCII 编码呢?
为了解决这个问题,出现了一种中间格式的字符集,即UTF(Unicode Transformation Format)。
常见的UTF格式有:
- UTF-7
- UTF-7.5
- UTF-8
- UTF-16
- UTF-32
其中我们需要重点了解的就是 UTF-8编码,即“可变长的编码”。
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,
常用的英文字母被编码成1个字节,汉字通常是3个字节,很生僻的字符会被编码成4-6个字节。
这里需要注意一点:
Python的诞生比Unicode标准发布的时间还要早,所以最早的Python只支持ASCII编码,
普通的字符串'ABC'在Python内部都是ASCII编码的。
而使用UTF-8编码还有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,
所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。
这也就是为什么我们每次在使用中文的时候都需要在文件开头声明 UTF-8 啦。
2.4 字符串的“切片”
当我们弄明白编程中令人苦恼的编码格式之后,我们就可以去使用我们的字符串啦。
例如我现在声明一个变量 name。
name = "lipeng"
那有一天我的学生霏姐想恶搞一下我,想把我名字中的一部分抽出来,这时候其实就要用到“切片”啦。
需要注意,字符串、列表、元组都支持切片操作。
首先先来说一下切片的语法:
切片的语法:[起始:结束:步长]
注意: 选取的区间属于左闭右开型,即从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身)。
那接下来来一个实际例子。
Last login: Tue Aug 7 09:27:48 on ttys000
➜ ~ python
>>> name = "lipeng"
>>> print(name[0:3])
lip
>>>
我们取到了下标0~2 的字符,那接下来我们测试一下0~4的字符。
Last login: Tue Aug 7 09:27:48 on ttys000
➜ ~ python
>>> name = "lipeng"
>>> print(name[0:5])
lipen
>>>
再来一个3~4的字符。
Last login: Tue Aug 7 09:27:48 on ttys000
➜ ~ python
>>> name = "lipeng"
>>> print(name[3:5])
en
>>>
那如果我们需要从某一个位置之后所有的数据呢?
Last login: Tue Aug 7 09:27:48 on ttys000
➜ ~ python
>>> name = "lipeng"
>>> print(name[2:])
peng
>>>
再假设,我们现在不知道总共内容有多长,但是知道需要截取到末尾的第几个,这时候应该怎么办呢?
Last login: Tue Aug 7 09:27:48 on ttys000
➜ ~ python
>>> name = "lipeng"
>>> print(name[1:-1])
ipen
>>>
如果你觉得自己已经明白切片的用法的话,可以自己试试以下题目:
>>> print(name[:3])
lip
>>> print(name[::2])
lpn
>>> print(name[5:1:2])
"" # 空
>>> print(name[1:5:2])
ie
>>> print(name[::-2])
gei
>>> print(name[5:1:-2])
ge
>>>
2.5 字符串中常用的方法
2.5.1 ord( ) : 获取字符的整数表示
➜ ~ python
>>> ord('a')
97
>>> ord('A')
65
>>> ord('0')
48
>>>
2.5.2 chr( ):编码转换为对应的字符
>>> chr(69)
'E'
>>> chr(103)
'g'
>>>
2.5.3 find( ):查询是否有对应文本
检测 str 是否包含在 mystr中,如果是返回开始的索引值,否则返回-1。
标准语法:mystr.find(str, start=0, end=len(mystr))
>>> name = "my name is MR_LP"
>>> name.find("MR_LP")
11
>>>
2.5.4 index( ):查询是否有对应文本
检测 str 是否包含在 mystr中,如果是返回开始的索引值,否则报错
标准语法:mystr.index(str, start=0, end=len(mystr))
>>> name = "my name is MR_LP"
>>> name.index("MR_LP")
11
>>> name.index("ZZZ")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
>>>
2.5.5 count( ):返回字符出现的次数
返回 str在start和end之间 在 mystr里面出现的次数
标准语法:mystr.count(str, start=0, end=len(mystr))
>>> name = "my name is MR_LP"
>>> name.count('m')
2
>>>
2.5.6 replace( ):替换文本,替换不超过 count 次
把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次.
标准语法:mystr.replace(str1, str2, mystr.count(str1))
>>> name = "my name is MR_LP"
>>> name.replace("MR_LP","233")
'my name is 233'
>>> name.replace("m","233",1)
'233y name is MR_LP'
>>>
2.5.7 split( ):按照分隔符将字符串切片
以 str 为分隔符切片 mystr,如果 maxsplit有指定值,则仅分隔 maxsplit 个子字符串
标准语法:mystr.split(str=" ", 2)
>>> name = "my name is MR_LP"
>>> name.split(' ')
['my', 'name', 'is', 'MR_LP']
>>> name.split(' ',2)
['my', 'name', 'is MR_LP']
>>>
2.5.8 capitalize( ):字符串首字母大写
把字符串的第一个字符大写
标准语法:mystr.capitalize()
>>> name = "my name is MR_LP"
>>> name.capitalize()
'My name is mr_lp'
>>>
2.5.9 title( ):字符串中每个单词首字母大写
把字符串的每个单词首字母大写
标准语法:name.title()
>>> name = "my name is MR_LP"
>>> name.title()
'My Name Is Mr_Lp'
>>>
2.5.10 startswith( ):检测字符串是否以某内容开头
检查字符串是否是以 obj 开头, 是则返回 True,否则返回 False
标准语法:mystr.startswith(obj)
>>> name = "my name is MR_LP"
>>> name.startswith('my')
True
>>> name.startswith('My')
False
>>>
2.5.11 endswith( ):检测字符串是否以某内容结尾
检查字符串是否是以 obj 结尾, 是则返回 True,否则返回 False
标准语法:mystr.endswith(obj)
>>> name = "my name is MR_LP"
>>> name.endswith('LP')
True
>>> name.endswith('lp')
False
>>>
2.5.12 lower( ):大写字符为小写
转换 mystr 中所有大写字符为小写
标准语法:mystr.lower()
>>> name = "my name is MR_LP"
>>> name.lower()
'my name is mr_lp'
>>>
2.5.13 所有大写字符为大写
转换 mystr 中所有大写字符为大写
标准语法:mystr.upper()
>>> name = "my name is MR_LP"
>>> name.upper()
'MY NAME IS MR_LP'
>>>
2.5.14 ljust( ):左对齐并填充字符串
返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
标准语法:mystr.ljust(width)
>>> s = "lipeng"
>>> s.ljust(10)
'lipeng '
>>>
2.5.15 rjust( ):右对齐并填充字符串
返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
标准语法:mystr.rjust(width)
>>> s = "lipeng"
>>> s.rjust(10)
' lipeng'
>>>
2.5.16 center( ):居中对齐并填充字符串
返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
标准语法:mystr.center(width)
>>> s = "lipeng"
>>> s.center(20)
' lipeng '
>>>
2.5.17 lstrip( ):清除左侧空白字符
删除 mystr 左边的空白字符
标准语法:mystr.lstrip()
>>> str = ' lipeng '
>>> str.lstrip()
'lipeng '
>>>
2.5.18 rstrip( ):清除右侧空白字符
删除 mystr 右边的空白字符
标准语法:mystr.rstrip()
>>> str = ' lipeng '
>>> str.rstrip()
' lipeng'
>>>
2.5.19 strip( ):清除左右两侧空白字符
删除 mystr 两侧的空白字符
标准语法:mystr.strip()
>>> str = ' lipeng '
>>> str.strip()
'lipeng'
>>>
2.5.20 rfind( ):从右侧查询是否有对应文本
从右侧查询是否有对应文本
标准语法:mystr.rfind(str, start=0,end=len(mystr) )
>>> name = "lipeng"
>>> name.rfind("p")
2
>>>
2.5.21 rindex( ):从右侧查询是否有对应文本
和 index( ) 相同,但是是从右侧开始
标准语法:mystr.rindex( str, start=0,end=len(mystr))
>>> name = "lipeng"
>>> name.rindex("e")
3
>>> name.rindex("LI")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
>>>
2.5.22 partition( ):以对应文本将字符串分割成三部分
把mystr以str分割成三部分,str前,str和str后
标准语法:mystr.partition(str)
>>> s = "i'm lipeng, you can call me MR_LP"
>>> s.partition("can")
("i'm lipeng, you ", 'can', ' call me MR_LP')
>>>
2.5.23 rpartition( ):从右侧以对应文本将字符串分割成三部分
从右侧把mystr以str分割成三部分,str前,str和str后
标准语法:mystr.rpartition(str)
>>> s = "i'm lipeng, you can call me MR_LP"
>>> s.rpartition("can")
("i'm lipeng, you ", 'can', ' call me MR_LP')
>>>
2.5.24 splitlines( ):按行分割
按照行分隔,返回一个包含各行作为元素的列表
标准语法:mystr.splitlines()
>>> s = "MR_LP.\nmr_lp"
>>> print(s)
MR_LP.
mr_lp
>>> s.splitlines()
['MR_LP.', 'mr_lp']
>>>
2.5.25 isalpha( ):判断是否全部是字母
如果 mystr 所有字符都是字母 则返回 True,否则返回 False
标准语法:mystr.isalpha()
>>> s = "abc"
>>> s.isalpha()
True
>>> s = "123"
>>> s.isalpha()
False
>>> s = "abc 123"
>>> s.isalpha()
False
2.5.26 isdigit( ):判断是否全部是数字
如果 mystr 只包含数字则返回 True 否则返回 False.
标准语法:mystr.isdigit()
>>> s = "abc"
>>> s.isdigit()
False
>>> s = "123"
>>> s.isdigit()
True
>>> s = "abc123"
>>> s.isdigit()
False
2.5.27 isalnum( ):判断是否全部是数字或字母
如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False
标准语法:mystr.isalnum()
>>> s = "123"
>>> s.isalnum()
True
>>> s = "abc"
>>> s.isalnum()
True
>>> s = "abc123"
>>> s.isalnum()
True
>>> s = "abc 123"
>>> s.isalnum()
False
2.5.28 isspace( ):判断是否只包含空格
如果 mystr 中只包含空格,则返回 True,否则返回 False.
标准语法:mystr.isspace()
>>> s = "abc123"
>>> s.isspace()
False
>>> s = ""
>>> s.isspace()
False
>>> s = " " # 空格
>>> s.isspace()
True
>>> s = " " # tab 键
>>> s.isspace()
True
2.5.28 join( ):判断是否只包含空格
如果 mystr 中只包含空格,则返回 True,否则返回 False.
标准语法:mystr.isspace()
>>> s = " "
>>> li = ["my","name","is","LIPENG"]
>>> s.join(li)
'my name is LIPENG'
>>> s = "_"
>>> li = ["my","name","is","LIPENG"]
>>> s.join(li)
'my_name_is_LIPENG'