零基础学Python--------第5章 字符串及正则表达式

时间:2021-11-12 10:38:20

第5章 字符串及正则表达式

5.1 字符串常用操作

在Python开发过程中,为了实现某项功能,经常需要对某些字符串进行特殊处理,如拼接字符串、截取字符串、格式化字符串等。下面将对Python中常用的字符串操作方法进行介绍。

5.1.1 拼接字符串

使用“+” 运算符可完成对多个字符串的拼接,“+” 运算符可以连接多个字符串并产生一个字符串对象。

例如,定义两个字符串,一个保存英文版的名言,另一个用于保存中文版的名言,然后使用“+” 运算符连接,代码如下:

mot_en = 'Remembrance is a form of meeting. Forgetfulness is a form of freedom.'
mot_cn = '记忆是一种相遇。遗忘是一种*。'
print(mot_en + '——' + mot_cn)

上面的代码执行后,将显示以下内容:

Remembrance is a form of meeting. Forgetfulness is a form of freedom.——记忆是一种相遇。遗忘是一种*。

字符串不允许直接与其他类型的数据拼接,例如,使用下面的代码将字符串与数值拼接在一起,将产生如下异常。

str1 = '我今天一共走了'         # 定义字符串
num = 2456 # 定义一个整数
str2 = '步' # 定义字符串
print(str1 + num + str2) # 对字符串和整数进行拼接
Traceback (most recent call last):
File "D:\python3.6.5\练习文件\demo.py", line 532, in <module>
print(str1 + num + str2) # 对字符串和整数进行拼接
TypeError: must be str, not int
>>>

解决该问题,可以将整数转换为字符串,然后以拼接字符串的方法输出该内容。将整数转换为字符串,可以使用str() 函数,修改后的代码如下:

str1 = '我今天一共走了'         # 定义字符串
num = 2456 # 定义一个整数
str2 = '步' # 定义字符串
print(str1 + str(num) + str2) # 对字符串和整数进行拼接

上面代码执行后,将显示以下内容:

我今天一共走了2456步

场景模拟:一天,两名程序员坐在一起聊天,于是产生了下面的笑话:程序员甲认为程序开发枯燥而辛苦,想换行,询问程序员乙该怎么办。而程序员乙让其敲一下回车键。试着用程序输出这一笑话。

实例01:使用字符串拼接输出一个关于程序员的笑话

创建一个文件,在该文件中定义两个字符串变量,分别记录两面程序员说的话,再将两个字符串拼接到一起,并且在中间拼接一个转义字符串(换行符),最后输出,代码如下:

programmer_1 = '程序员甲:搞IT太辛苦了,我想换行……怎么办?'
programmer_2 = '程序员乙:敲一下回车键'
print(programmer_1 + '\n' + programmer_2)

运行结果如下:

程序员甲:搞IT太辛苦了,我想换行……怎么办?
程序员乙:敲一下回车键

5.1.2 计算字符串的长度

由于不同的字符所占字节数不用,所以要计算字符串的长度,需要先了解各字符所占的字节数。在Python 中,数字、英语、小数点、下划线和空格占一个字节;一个汉字可能会占2~4个字节,占几个字节

取决于采用的编码。汉字在GBK/GB2312 编码中占2 个字节,在UTF-8/unicode 编码中一般占用3 个字节(或4 个字节)。下面以Python 默认的UTF-8 编码为例进行说明,即一个汉字占3 个字节。

在Python 中,提供了len() 函数计算字符串的长度,语法格式如下:

len(string)

其中,string 用于指定要进行长度统计的字符串。例如,定义一个字符串,内容为“人生苦短,我用Python!”,然后应用len() 函数计算该字符串的长度,代码如下:

str1 = '人生苦短,我用Python!'             # 定义字符串
length = len(str1) # 计算字符串的长度
print(length)

上面的代码在执行后,将输出结果‘14’。

从上面的结果中可以看出,在默认的情况下,通过len() 函数计算字符串的长度,不区分英文,数字和汉字,所有字符都按一个字符计算。

在实际开发时,有时需要获取字符串实际所占的字节数,即如果采用UTF-8 编码,汉字占3 个字节,采用GBK 或者GB2312 时,汉字占2 个字节。这时,可以通过使用encode() 方法(参加5.2.1 小节)进行编码后再进行获取。例如,如果获取采用UTF-8 编码的字符串的长度,可以使用下面的代码:

str1 = '人生苦短,我用Python!'                       # 定义字符串
length = len(str1.encode ()) # 计算UTF-8编码的字符串的长度
print(length)

……

如果要获取采用GBK 编码的字符串的长度,可以使用下面的代码。

str1 = '人生苦短,我用Python!'                             # 定义字符串
length = len(str1.encode ('gbk')) # 计算UTF-8编码的字符串的长度
print(length)

5.1.3 截取字符串

由于字符串也属于序列,所以要截取字符串,可以采用切片方法实现。通过切片方法截取字符串的语法格式如下:

string[start:end:step]

参数说明:

  • string:表示要截取的字符串。
  • start:表示要截取的第一个字符的索引(包括该字符),如果不指定,则默认为0。
  • end:表示要截取的最后一个字符的索引(不包括该字符),如果不指定则默认字符串的长度。
  • step:表示切片的步长,如果省略,则默认为1,当省略该步长时,最后一个冒号也可以省略。

说明:字符串的索引同序列的索引是一样的,也是从0 开始,并且每个字符占一个位置。

例如,定义一个字符串,然后应用切片方法截取不同长度的字符串,并输出,代码如下:

str1 = '人生苦短,我用Python!'           # 定义字符串
substr1 = str1[1] # 截取第2个字符
substr2 = str1[5:] # 从第6个字符截取
substr3 = str1[:5] # 从左边开始截取第5个字符
substr4 = str1[2:5] # 截取第3个到第5个字符
print('原字符串:',str1)
print(substr1 + '\n' + substr2 + '\n' + substr3 + '\n' + substr4)

上面的代码执行后,将显示以下内容:

原字符串: 人生苦短,我用Python!

我用Python!
人生苦短,
苦短,

……

实例02:截取身份证号码的出生日期

……截取出初设是哪个日期,并组合成YYYY年MM月DD日“”格式的字符串,最后输出截取到的出生日期和生日,代码如下:

programer_1 = '你知道我的生日吗?'            # 程序员甲问程序员乙的台词
print('程序员甲说:',programer_1) # 输出程序员甲的台词
programer_2 = '输入你的身份证号码。' # 程序员乙的台词
print('程序员乙说:',programer_2) # 输出程序员乙的台词
idcard = '' # 定义保存身份证号码的字符串
print('程序员甲说:',idcard) # 程序员甲说出身份证号码
birthday = idcard[6:10] + '年' + idcard[10:12] + '月' + idcard[12:14] + '日' # 截取生日
print('程序员乙说:','你是' + birthday + '出生的,所以你的生日是' + birthday[5:])

运行结果如下:

程序员甲说: 你知道我的生日吗?
程序员乙说: 输入你的身份证号码。
程序员甲说: 101252198501058866
程序员乙说: 你是1985年01月05日出生的,所以你的生日是01月05日

5.1.4 分割、合并字符串

在Python 中,字符串对象提供了分割和合并字符串的方法。分割字符串是把字符串分割为列表,而合并字符串是把列表合并为字符串,分割字符串和合并字符串可以看作是互逆操作。

1. 分割字符串

字符串对象的split() 方法可以实现字符串分割,也就是把一个字符串按照指定的分隔符切分为字符串列表。该列表的元素中,不包括分隔符。split() 方法的语法格式如下:

str.split(sep,maxsplit)

参数说明:

  • str:表示要进行分割的字符串。
  • sep:用于指定分隔符,可以包含多个字符,默认为None,即所有空字符(包括空格、换行“\n”、制表符“\t”等)。
  • maxsplit:可选参数,用于指定分割的次数,如果不指定或者为-1,则分割次数没有限制,否则返回结果列表的元素个数,个数最多为maxsplit+1。
  • 返回值:分隔后的字符串列表。

说明:在split() 方法中,如果不指定sep 参数,那么也不能指定maxsplit 参数。

例如,定义一个保存博客园网站的字符串,然后应用split() 方法根据不同的分隔符进行分割,代码如下:

str1 = '博 客 园 官 网 >>> www.cnblogs.com/'
print('原字符串:',str1)
list1 = str1.split() # 采用默认分隔符进行分割
list2 = str1.split('>>>') # 采用多个字符进行分割
list3 = str1.split('.') # 采用.号进行分割
list4 = str1.split(' ',4) # 采用空格进行分割,并且只分割前4个
print(str(list1) + '\n' + str(list2) + '\n' + str(list3) + '\n' + str(list4))
list5 = str1.split('>') # 采用>进行分割
print(list5)

上面的代码在执行后,将显示以下内容:

原字符串: 博 客 园 官 网 >>> www.cnblogs.com/
['博', '客', '园', '官', '网', '>>>', 'www.cnblogs.com/']
['博 客 园 官 网 ', ' www.cnblogs.com/']
['博 客 园 官 网 >>> www', 'cnblogs', 'com/']
['博', '客', '', '园', '官 网 >>> www.cnblogs.com/']
['博 客 园 官 网 ', '', '', ' www.cnblogs.com/']

说明:在使用split() 方法时,如果不指定参数,默认采用空白符进行分割,这是无论有几个空格或者空白符都将作为一个分隔符进行分割。……

场景模拟:微博的@好友栏目中,输入“@马云 @雷军 @马化腾”(好友之间用一个空格区分),同时@三个好友。

实例03:输出被@三个好友。

在IDLE中创建一个名称为atfriend.py 的文件,然后在该文件中定义一个字符串,内容为“@马云 @雷军 @马化腾”,然后使用split() 方法对该字符串进行分割,从而取出好友名称,并输出,代码如下:

str1 ='@马云 @雷军 @马化腾'
list1 = str1.split(' ') # 用空格分隔字符串
print('您@的好友有:')
for item in list1:
print(item[1:]) # 输出每个好友名字时,去掉@符号

运行结果如下:

您@的好友有:
马云
雷军
马化腾

2. 合并字符串

合并字符串与拼接字符串不同,它会将多个字符串采用固定的分隔符连接在一起。例如,字符串“灰灰*木马*小丽*莱德”,就可以看做是通过分隔符“ * ” 将['灰灰';'木马','小丽'',莱德']列表合并为一个字符串的结果。

合并字符串可以使用字符串对象的join() 方法实现,语法格式如下:

strnew = string.join(iterable)

参数说明:

  • strnew:表示合成后生成新的字符串。
  • string:字符串类型,用于指定合并时的分隔符。
  • iterable:可迭代对象,该迭代对象中的所有元素(字符串表示)将被合并为一个新的字符串。string 作为边界点分割出来。

场景模拟:微博的@好友栏目中,输入“@马云 @雷军 @马化腾”(好友之间用一个空格区分),即可同时@三个好友。现在想要@好友列表中的全部好友,所以需要组合一个类似的字符串。

实例04:通过好友列表生成全部被@的好友

在IDLE 中创建一个名称为atfriend-join.py 的文件,然后在该文件中定义一个列表,保存一些好友名称,然后使用 join() 方法将列表中每个元素用空格 +@ 符号进行连接,再在连接后的字符串前添加一个 @ 符号,最后输出,代码如下:

list_friend =['马云','雷军','马化腾','王永林','牛根生']     # 好友列表
str_friend = ' @'.join (list_friend) # 用空格+@符号进行连接
at = '@'+str_friend #由于使用join() 方法时,第一个元素前不加分隔符,所以需要在前面加上@符号
print('您要@的好友:',at) # 输出每个好友名字时,去掉@符号

运行结果如下:

您要@的好友: @马云 @雷军 @马化腾 @王永林 @牛根生

5.1.5 检索字符串

在Python中,字符串对象提供了很多应用于字符串查找的方法,这里介绍以下几种方法,这里主要介绍以下几种方法。

1. count() 方法

count() 方法用于检索指定字符串在另一个字符串中出现的次数。如果检索的字符串不存在,则返回0,否则返回出现的次数。其语法格式如下:

str.count(sub[, start[, end]])

参数说明:

  • str:表示原字符串。
  • sub:表示要检索的子字符串。
  • start:可选参数,表示检索范围的起始位置的索引,如果不指定,则从头开始检索。
  • end:可选参数,表示检索范围的结束位置的索引,如果不指定,则一直检索到结尾。

例如,定义一个字符串,然后应用count() 方法检索该字符串“@”符号出现的次数,代码如下:

str1 ='@马云 @雷军 @马化腾'
print('字符串“',str1,'”中包括',str1.count('@'),'个@符号')

上面的代码执行后,将显示以下结果:

字符串“ @马云 @雷军 @马化腾 ”中包括 3 个@符号

2. find() 方法

该方法用于检索是否包含指定的子字符串。如果检索的字符串不存在,则返回-1,否则返回首次出现该子字符串时的索引。其语法格式如下:

str.find(sub[, start[, end]])

参数说明:

  • str:表示原字符串。
  • sub:表示要检索的子字符串。
  • start:可选参数,表示检索范围的起始位置的索引,如果不指定,则从头开始检索。
  • end:可选参数,表示检索范围的结束位置的索引,如果不指定,则一直检索到结尾。

例如,定义一个字符串,然后应用find() 方法检索该字符串中首次出现“@”符号的位置索引,代码如下:

str1 ='@马云 @雷军 @马化腾'
print('字符串“',str1,'”中@符号首次出现的位置索引为:',str1.find('@'))

上面的代码执行后,将显示以下结果:

字符串“ @马云 @雷军 @马化腾 ”中@符号首次出现的位置索引为: 0

说明:如果只是想要判断指定的字符串是否存在,可以使用in 关键字实现。例如,上面的字符串str1 中是否存在@符号,可以使用print(‘@’in str1) ,如果存在就返回True,否则返回False。另外,也可以根据find() 方法的返回值是否大于-1来确定的字符串是否存在。

如果输入的子字符串在原字符串中不存在,将返回-1。例如下面的代码:

str1 ='@马云 @雷军 @马化腾'
print('字符串“',str1,'”中*符号首次出现的位置索引为:',str1.find('*'))

上面的代码执行后,将显示以下结果:

字符串“ @马云 @雷军 @马化腾 ”中*符号首次出现的位置索引为: -1

说明:Python的字符串对象还提供了rfind() 方法,其作用于find() 方法类似,只是从字符串右边开始查找。

3. index() 方法

index() 方法同find() 方法类似,也是用于检索是否包含指定的子字符串。只不过如果使用index() 方法,当指定的字符串不存在时会抛出异常。其语法格式如下:

str.index(sub[, star[, end]])

参数说明:

  • str:表示原字符串。
  • sub:表示要检索的子字符串。
  • start:可选参数,表示检索范围的起始位置的索引,如果不指定,则从头开始检索。
  • end:可选参数,表示检索范围的结束位置的索引,如果不指定,则一直检索到结尾。
  • 例如,定义一个字符串,然后应用index() 方法检索该字符串中首次出现“@”符号的位置索引,代码如下:
str1 ='@马云 @雷军 @马化腾'
print('字符串“',str1,'”中@符号首次出现的位置索引为:',str1.index('@'))

上面的代码执行后,将显示以下结果:

字符串“ @马云 @雷军 @马化腾 ”中@符号首次出现的位置索引为: 0

如果输入的子字符串在原字符串中不存在,将会产生异常,例如下面的代码:

str1 ='@马云 @雷军 @马化腾'
print('字符串“',str1,'”中*符号首次出现的位置索引为:',str1.index('*'))

上面的代码执行后,将显示如下异常:

Traceback (most recent call last):
File "D:\python3.6.5\练习文件\demo.py", line 621, in <module>
print('字符串“',str1,'”中*符号首次出现的位置索引为:',str1.index('*'))
ValueError: substring not found

说明:Python的字符串对象还提供了rindex() 方法,其作用于index() 方法类似,只是从右边开始查找。

4. startswith() 方法

starswith() 方法用于检索字符串是否以指定子字符串开头。如果是则返回True,否则返回False。该方法语法格式如下:

str.startswith(prefix[, start[, end]])

参数说明:

  • str:表示原字符串。
  • prefix:表示要检索的子字符串。
  • start:可选参数,表示检索范围的起始位置的索引,如果不指定,则从头开始检索。
  • end:可选参数,表示检索范围的结束位置的索引,如果不指定,则一直检索到结尾。
  • 例如,定义一个字符串,然后应用startswith() 方法检索该字符串中首次出现“@”符号的位置索引,代码如下:
str1 ='@马云 @雷军 @马化腾'
print('字符串“',str1,'”是否以@符号开头,结果为:',str1.startswith('@'))

上面的代码执行后,将显示以下结果:

字符串“ @马云 @雷军 @马化腾 ”是否以@符号开头,结果为: True

5. endswinth() 方法

endswinth() 方法用于检索字符串是否以指定的子字符串结尾。如果是则返回True,否则返回False。该方法语法格式如下:

str.endswith(suffix[, start[, end]])

参数说明:

  • str:表示原字符串。
  • suffix:表示要检索的子字符串。
  • start:可选参数,表示检索范围的起始位置的索引,如果不指定,则从头开始检索。
  • end:可选参数,表示检索范围的结束位置的索引,如果不指定,则一直检索到结尾。
  • 例如,定义一个字符串,然后应用endswith() 方法检索该字符串是否以“.com”结尾,代码如下:
str1 ='https://www.cnblogs.com'
print('字符串“',str1,'”是否以.com结尾,结果为:',str1.endswith('.com'))

上面的代码执行后,将显示以下结果:

字符串“ https://www.cnblogs.com ”是否以.com结尾,结果为: True

5.1.6 字母的大小写转换

在Python中,字符串对象提供了lower() 方法和upper() 方法进行字母的大小写转换,即可用于将大写字符转换为小写字母或者将小写字母转换为大写字母。

1.lower() 方法

lower() 方法用于将字符串中的大写字母转换为小写字母。如果字符串中没有需要被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个需要进行小写转换的字符都转换成等价的小写字符。字符长度与元字符长度相同。lower() 方法的语法格式如下:

str.lower()

其中,str 为要进行转换的字符串。

例如,使用lower() 方法后,下面定义的字符串将全部显示为小写字母。

str1 ='https://WWW.cnblogs.Com'
print('字符串',str1)
print('新字符串',str1.lower()) # 全部转换为小写字母输出

2. upper() 方法

upper() 方法用于将字符串中的小写字母转换为大写字母。……

str.upper()
str1 ='https://www.cnblogs.com'
print('字符串',str1)
print('新字符串',str1.upper()) # 全部转换为大写字母输出

实例05:不区分大小写验证会员名是否唯一

代码如下:

# 假设已经注册的会员名称保存在一个字符串中,以“|”进行分割
username_1 = '|LiaoXi|liaoxi|sy|SHENYANG|'
username_2 = username_1.lower() # 将会员名称字符串全部转换为小写
regname_1 = input('输入要注册的会员名称:')
regname_2 = '|' + regname_1.lower() + '|' # 将要注册的会员名称全部转换为小写
if regname_2 in username_2: # 判断输入的会员名称是否存在
print('会员名',regname_1,'已经存在!')
else:
print('会员名',regname_1,'可以注册了!')

5.1.7 去除字符串中的空格和特殊字符

用户在输入数据时,可能会无意中输入多余的空格,或在一些情况下,字符串前后不允许出现空格和特殊字符,此时就需要去除字符串中的空格和特殊字符。……

说明:这里的特殊字符是指制表符\t、回车符\r、换行符\n等。

1. strip() 方法

strip() 方法用于去掉字符串左、右两侧的空格和特殊字符,语法格式如下:

str.strip([chars])

参数说明 :

  • str:为要去除空格的字符串。
  • chars:为可选参数,用于指定要去除的字符,可以指定多个。如果设置chars 为“@.”,则去除左、右两侧包括的“@” 或“.”。如果不指定chars 参数,默认将去除空格、制表符“\t”、回车符“\r”、换行符“\n”等。

例如,先定义一个字符串,首尾包括空格、制表符、换行符和回车符等,然后去除空格和这些特殊字符;再定义一个字符串,首尾包括“@” 或“.” 字符,最后去掉“@” 或“.”,代码如下:

str1 = '    https://www.cnblogs.com   \t\n\r'
print('原字符串str1:' + str1 + '。')
print('字符串',str1.strip() + '。') # 去除字符串首尾的空格和特殊字符
str2 = '@博客园.@.'
print('原字符串str1:' + str2 + '。')
print('字符串',str2.strip('@.') + '。') # 去除字符串首尾的空格和特殊字符

运行结果如下:

原字符串str1:    https://www.cnblogs.com       

。
字符串 https://www.cnblogs.com。
原字符串str1:@博客园.@.。
字符串 博客园。

2. Istrip() 方法

lstrip() 方法用于去掉字符串左侧的空格和特殊字符,语法格式如下:

str.lstrip([chars])

参数说明:

  • str:为要去除空格的字符串。
  • chars:为可选参数,用于指定要去除的字符,可以指定多个。如果设置chars 为“@.”,则去除左、右两侧包括的“@” 或“.”。如果不指定chars 参数,默认将去除空格、制表符“\t”、回车符“\r”、换行符“\n”等。

……

3. rstrip() 方法

rstrip() 方法用于去掉字符串左侧的空格和特殊字符,语法格式如下:

str.rstrip([chars])

参数说明:

  • str:为要去除空格的字符串。
  • chars:为可选参数,用于指定要去除的字符,可以指定多个。如果设置chars 为“@.”,则去除左、右两侧包括的“@” 或“.”。如果不指定chars 参数,默认将去除空格、制表符“\t”、回车符“\r”、换行符“\n”等。

……

5.1.8 格式化字符串

格式化字符串是指先制定一个模板,在这个模板中预留几个空位,然后再根据需要填上相应的内容。这些空位需要通过制定的符号标记(也称为占位符),而这些符号还不会显示出来。在Python 中,格式化字符串有以下两种方法:

1. 使用“%”操作符

在Python 中,要实现格式化字符串,可以使用“%” 操作符,语法格式如下:

'%[-][+][0][m][.n]格式化字符'%exp

参数说明:

  • -:可选参数,用于指定左对齐,证书前方无符号,负数前方加负号。
  • +:可选参数,用于指定右对齐,正数前方加正号,负数前方加负号。
  • 0:可选参数,表示右对齐,正数前方无符号,负数前方加负号,用0填充空白处(一般与m 参数一起使用) 。
  • m:可选参数,表示占有宽度。
  • .n:可选参数,表示小数点后保留的位数。
  • 格式化字符:用于指定类型,其值如下边所示。
常用的格式化符号
格式化字符 说明 格式化字符 说明
%s 字符串(采用str())显示 %r 字符串(采用repr()显示)
%c 单个字符 %o 八进制整数
%d 或者 %i 十进制整数 %e 指数(基底写为e)
%x 十六进制整数 %E 指数(基底写为E)
%f 或者 %F 浮点数 %% 字符%
  • exp:要转换的项。如果要指定的项有多个,需要通过元组的形式进行指定,但不能使用列表。

例如,格式化输出一个保存公司信息的字符串,代码如下:

template = '编号:%09d\t公司名称: %s \t官网:http://www.%s.com'    # 定义模板
context1 = (7,'百度','baidu') # 定义要转换的内容1
context2 = (8,'博客园','cnblogs') # 定义要转换的内容2
print(template%context1) # 格式化输出
print(template%context2) # 格式化输出

上面的代码运行后将显示下面效果,即按照指定模板格式输出两条公司信息。

编号:00007    公司名称: 百度     官网:http://www.baidu.com
编号:00008 公司名称: 博客园 官网:http://www.cnblogs.com

说明:由于使用% 操作符是早期Python 中提供的方法,自从Python 2.6版本开始,字符串对象提供了format() 方法对字符串进行格式化。现在一些Python 社区也推荐使用这种方法。所以建议大家重点学校format() 方法的使用。

2. 使用字符串对象的format() 方法

字符串对象提供了format() 方法用于进行字符串格式化,语法格式如下:

str.format(args)

参数说明:

  • str: 用于指定字符串的显示样式(即模板)。
  • args:用于指定要转换的项,如果有多项,则用逗号进行分隔。

下面重点介绍创建模板。在创建模板时,需要使用“{}”和“:”指定占位符,语法格式如下:

{[index][:[fill]align][sign][#][width][.precision][type]]}

参数说明:

  • index:可选参数,用于指定要设置格式的对象在参数列表中的索引位置,索引值从0开始。如果省略,则根据值的先后顺序自动分配。
  • fill:可选参数,用于指定空白处填充的字符。
  • align:可选参数,用于指定对齐方式(值为“<”是表示内容左对齐;值为“>”时表示内容右对齐;值为“=”时表示内容右对齐,将符合放在填充内容的最左侧,且值对数字类型有效;值为“^”时表示内容居中),需要配合width一起。
  • sign:可选参数,用于指定有无符号数(值为“+”表示正数加正号,负数加负号;值为“-”表示正数不变;负数加负号,值为空格表示正数加空格,负数加负号)。
  • #:可选参数,对于二进制数、八进制数和十六进制数,如果加上#,表示会显示0b/0o/0x前缀,否则不显示前缀。
  • width:可选参数,用于指定所占宽度。
  • .precision:可选参数,用于指定保留的小数位数。
  • type:可选参数,用于指定类型。

format() 方法中常用的格式化字符如下:

format() 方法中常用的格式化字符
格式化 说明 格式化字符 说明
s 对字符串类型格式化 b 将十进制整数自动转换成二进制表示再格式化
d 十进制整数 o 将十进制整数自动转换成八进制表示再格式化
c 将十进制整数自动转换成对应的Unicode字符 x 或者 X 将十进制整数自动转换成十六进制表示再格式化
e 或者 E 转换为科学计数法表示再格式化 f 或者 F 转换为浮点数(默认小数点后保留6位)再格式化
g 或者 G 自动在 e 和 f 或者 E 和 F 中切换 % 显示百分比(默认显示小数点后6位)

说明:当一个模板中,出现多个占位符时,指定索引位置的规范需统一,即全部采用手动指定,或者全部采用自动。例如,定义“'我是数值:{:d},我是字符串:{1:s}'” 模板是错误的。

例如,定义一个保存公司信息的字符串模板,然后应用该模板输出不同公司的信息,代码如下:

template = '编号:{:0>9s}\t公司名称: {:s} \t官网:http://www.{:s}.com'    # 定义模板
context1 = template.format('','百度','baidu') # 转换的内容1
context2 = template.format('','博客园','cnblogs') # 转换的内容2
print(context1) # 输出格式化后的字符串
print(context2) # 输出格式化后的字符串

上面代码运行后如下:

编号:000000007    公司名称: 百度     官网:http://www.baidu.com
编号:000000008 公司名称: 博客园 官网:http://www.cnblogs.com

在实际开发中,数值类型有多种显示方式,比如货币形式、百分比形式等,使用format() 方法可以将数值格式化为不同的形式。下面通过一个具体的实例进行说明。

实例06:格式化不同的数值类型数据

将不同类型的数据进行格式化并输出,代码如下:

import math                 # 导入Python的数字模块
# 以货币形式显示
print('51234+12354的结果是(以货币形式显示):¥{:,.2f}元'.format(51234+12354))
print('{0:.1f}用科学计数法表示:{0:E}'.format(120000.1)) # 用科学计数法表示
print('π取5位小数:{:.5f}'.format(math.pi)) # 输出小数点后五位
print('{0:d}的16进制结果是:{0:#x}'.format(100)) # 输出十六进制
# 输出百分比,并且不带小数
print('天才是由{:.0%}的灵感,加上{:.0%}的汗水。'.format(0.01,0.99))

运行实例,将显示如下结果。

51234+12354的结果是(以货币形式显示):¥63,588.00元
120000.1用科学计数法表示:1.200001E+05
π取5位小数:3.14159
100的16进制结果是:0x64
天才是由1%的灵感,加上99%的汗水。 

5.2 字符串编码转换

……在Python 3.X 中,默认采用的编码格式为UTF-8,采用这种编码有效地解决了中文乱码的问题。

在Python 中,有两种常用的字符串类型,分别为str 和bytes。其中,str 表示Unicode 字符(ASCII 或者其他);bytes 表示二进制数据(包括编码的文本)。这两种类型的字符串不能拼接在一起使用。通常情况下,str 在内存中以 Unicode 表示,一个字符对应若干个字节。但是如果在网络上传输,或者保存到磁盘上,就需要把str 转换为字节类型,即bytes 类型。

说明:bytes类型的数据是带有b 前缀的字符串(用单引号或双引号表示),例如,b'\xd2\xb0'和b'mr' 都是bytes类型的数据。

str类型和bytes类型之间可以通过encode() 和 decode() 方法进行转换,这两个方法是互逆的过程。

5.2.1 使用encode() 方法编码

encode() 方法为 str 对象的方法,用于将字符串转换为二进制数据(即bytes),也称为“编码”,其语法格式如下:

str.encode([encoding="utf-9"][,errors="strict"])

参数说明:

  • str:表示要进行转换的字符串。
  • encoding="utf-8" :可选参数,用于指定进行转码时采用的字符编码,默认为UTF-8,如果想使用简体中文,也可以设置为gb2312。当只有这一个参数时,也可以省略前面的“encoding=”,直接写编码。
  • errors=“strict”:可选参数,用于指定错误处理方式,其可选择值可以是strict(遇到非法字符就抛出异常)、ignore(忽略非法字符)、replace(用“?”替换非法字符)或xmlcharrefreplace(使用XML 的字符引用)等,默认值为strict。

说明:在使用encode() 方法时,不会修改原字符串,如果需要修改原字符串,需要对其进行重新赋值。

例如,定义一个名称为verse 的字符串,内容为“野渡无人舟自横”,然后使用endoce() 方法将其采用GBK 编码转换为二进制数,并输出原字符串和转换后的内容,代码如下:

verse = '野渡无人舟自横'
byte = verse.encode('GBK') # 采用GBK编码转换为二进制数据,不处理异常
print('原字符串:',verse) # 输出原字符串(没有改变)
print('转换后:',byte) # 输出转换后的二进制数据

上面的代码执行后,将显示以下内容:

原字符串: 野渡无人舟自横
转换后: b'\xd2\xb0\xb6\xc9\xce\xde\xc8\xcb\xd6\xdb\xd7\xd4\xba\xe1'

如果采用UTF-8 编码,转换后的二进制数据为:

原字符串: 野渡无人舟自横
转换后: b'\xe9\x87\x8e\xe6\xb8\xa1\xe6\x97\xa0\xe4\xba\xba\xe8\x88\x9f\xe8\x87\xaa\xe6\xa8\xaa'

5.2.2 使用decode() 方法编码

decode() 方法为bytes 对象的方法用于将二进制数据转换为字符串,即将使用encode() 方法转换的结果再转换为字符串,也称为“解码”。语法格式如下:

bytes.decode([encoding="utf-8"][,errors="strict"])

参数说明:

  • bytes:表示要进行转换的二进制数据,通常是encode() 方法转换的结果。
  • encoding="utf-8" :可选参数,用于指定进行解码时采用的字符编码,默认为UTF-8,如果想使用简体中文,也可以设置为gb2312。当只有这一个参数时,也可以省略前面的“encoding=”,直接写编码。

注意:在设置解码采用的字符编码时,需要与编码时采用的字符编码一致。

  • errors=“strict”:可选参数,用于指定错误处理方式,其可选择值可以是strict(遇到非法字符就抛出异常)、ignore(忽略非法字符)、replace(用“?”替换非法字符)或xmlcharrefreplace(使用XML 的字符引用)等,默认值为strict。

说明:在使用decode() 方法时,不会修改原字符串,如果需要修改原字符串,需要对其进行重新赋值。

例如,将5.2.1 小节中的示例编码后会得到二进制数据(保存在变量byte 中),要进行解码可以使用下面的代码:

verse = '野渡无人舟自横'
byte = verse.encode('GBK') #采用GBK编码转换为二进制数据,不处理异常
print('解码后:',byte.decode("GBK")) # 对进行制数据进行解码

上面的代码执行后,将显示以下内容:

解码后: 野渡无人舟自横

5.3 正则表达式

在处理字符串时,经常会有查找符合某些赋复杂规则的字符串的需求。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。对于接触过DOS 的用户来说,如果想匹配当前文件夹下所有的文本文件,可以输入“dir *.txt” 命令,按<Enter>键后,所有“.txt” 文件将会被列出来。这里的“*.txt” 即可理解为一个简单的正则表达式。

5.3.1 行定位符

行定位符就是用来描述字符串的边界,“^” 表示行的开始,“$” 表示行的结尾。如:

^tm

该表达式表示要匹配字符串tm 的开始位置是行头,如“tm equal Tomorrow Moon” 可以匹配,而“Tomorrow Moon equal tm” 则不匹配。但如果使用:

tm$

后者可以匹配而前者不能匹配。如果要匹配的字符串可以出现在字符串的任意部分,那么可以直接写成下面的格式,这样两个字符串就都可以匹配了。

tm

5.3.2 元字符

除了前面介绍的元字符“^” 和“$” 外,正则表达式里还有更多的元字符,例如下面的正则表达式中就应用了元字符“\b” 和“\w”。

\bmr\w*\b

上面的正则表达式用于匹配以字母mr 开头的单词,先从某个单词开始处(\b),然后匹配字母mr,接着是任意数量的字母或数字(\w*),最后单词结束处(\b)。该表达式可以匹配“mrsoft” “nmr” 和“mr123456等,但不能与“amr”匹配。更多常用元素符见下表。

常用元字符
代码 说明

举例

. 匹配除换行符以外的任意字符

. 可以匹配“mr\nM\tR”中的m、r、M、\t、R

\w 匹配字母、数字、下划线或汉字

\w 可以匹配“m 中 7r\n”中的“m、中、7、r”,但

不能匹配\n

\W 匹配除字母、数字、下划线或汉字以外的字符

\W 可以匹配“m 中 7r\n”中的“n,但不能匹配“m、中、7、r”

\s 匹配单个的空白符(包括Tab键和换行符)

\s 可以匹配“mr\tMR”中的\t

\S

除单个空白符(包括Tab键和换行符)以外的

所有字符

\S 或可以匹配“mr\tMR”中的m、r、M、R
\b

匹配单词的开始或结束,单词的分解符通常是

空格,标点符号或者换行

在“I like mr or am”字符串中,\bm与mr中的m相匹配,但与

am中的m 不匹配

\d 匹配数字

\d 可以与“m7ri” 中的字符7 匹配

5.3.3 限定符

在上面例子中,使用(\w*)匹配任意数量的字母或数字。如果想匹配特定数量的数字,该如何表示呢?正则表达式为我们提供了限定符(指定数量的字符)来实现该功能。如匹配8 位QQ 号可以如下表达式:

^\d{8}$

常见的限定符见下表

……

5.3.4 字符类

……

5.3.5 排除字符

……

5.3.6 选择字符

……

5.3.7 转义字符

……

5.3.8 分组

……

5.3.9 在Python中使用正则表达式语法

……

5.4 使用 re 模块实现正则表达式操作

……

5.4.1 匹配字符串

匹配字符串可以使用re 模块提供的match()、search() 和findall() 等方法。

1. 使用match() 方法进行匹配

match() 方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回Match 对象,否则返回None。其语法格式如下:

re.match(pattern,string,[flags])

参数说明:

  • pattern:表示模式字符串,由要匹配的正则表达式转换而来。
  • string:表示要匹配的字符串。
  • flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。常用的标志如表5.5 所示。
表5.5 常用标志
标志 说明
   
   
   
   
   

……

实例07:

……

2. 使用search() 方法进行匹配

search() 方法用于在整个字符串中搜索第一个匹配的值,如果匹配成功,则返回Match对象,否则返回None。search() 方法的语法格式如下:

re.search(pattern,string,[flags])

参数说明:

  • pattern:表示模式字符串,由要匹配的正则表达式转换而来。
  • string:表示要匹配的字符串。
  • 可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。常用的标志如表5.5所示。

例如,搜索第一个以“mr_”  开头的字符串,不区分字母大小写,代码如下:

……

实例08:

……

3. 使用findall() 方法进行匹配

findall() 方法用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回。如果匹配成功,则返回包含匹配结构的列表,否则返回空列表。findall() 方法的语法格式如下:

re.findall(pattern,string,[flags])

参数说明:

pattern:表示模式字符串,由要匹配的正则表达式转换而来。

string:表示要匹配的字符串。

flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。常用的标志如5.5所示。

例如,搜索以“mr_” 开头的字符串,代码如下:

……

5.4.2 替换字符串

sub() 方法用于实现字符串替换,语法格式如下:

re.sub(pattern,repl,string,count,flags)

参数说明:

  • pattern:表示模式字符串,由要匹配的正则表达式转换而来。
  • repl:表示替换的字符串。
  • string:表示要被查找替换的原始字符串。
  • count:可选参数,表示模式匹配后替换的最大次数,默认值为0,表示替换所有的匹配。
  • flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。常用的标志如表5.5所示。

例如,隐藏中奖信息中的手机号码,代码如下:

import re
pattern = r'1[34578]\d{9}' # 定义要替换的模式字符串
string = '中奖号码为:468451646546 联系电话:13855556666'
result = re.sub(pattern,'1xxxxxxxxxx',string) # 替换字符串
print(result)

执行结果如下:

中奖号码为:468451646546 联系电话:1xxxxxxxxxx

实例09:替换出现的危险字符

……

5.4.3 使用正则表达式分割字符串

split() 方法用于实现根据正则表达式分割字符串,并以列表的形式返回。其作用同字符串对象的split() 方法类似,所不同的就是分割字符由模式字符串指定。split() 方法的语法格式如下:

re.split(pattern,string,[maxsplit],[flags])

参数说明:

  • pattern:表示模式字符串,由要匹配的正则表达式转换而来。
  • string:表示要匹配的字符串。
  • maxsplit:可选参数,表示最大的拆分次数。
  • flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。常用的标志如5.5所示。

例如,从给定的URL地址中提取出请求地址和各个参数,代码如下:

import re
pattern = r'[?|&]' # 定义分隔符
url = 'http://www.mingrisoft.com/login.jsp?username="mr"&pwd="mrsoft"'
result = re.split(pattern,url) # 分割字符串
print(result)

执行结果如下:

['http://www.mingrisoft.com/login.jsp', 'username="mr"', 'pwd="mrsoft"']

场景模拟:……

实例10:输入被@的好友名称(应用正则表达式)

……

5.5 实战

……