06 - Python 中的字符串

626 阅读12分钟

一、前言

大家好,我是更新看缘分的李鹏李先生。

本次课程主讲 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 ~ 9A ~ Za ~ 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'