写点什么

8. 字符串详解

作者:茶桁
  • 2023-08-06
    上海
  • 本文字数:5174 字

    阅读完需:约 17 分钟

Hi, 大家好。我是茶桁。


前几节课中我们学习了函数,那么这节课开始,我们花几节课返过头来详细的学习一下 Python 内的数据类型。第一节课,让我们先从字符串开始:



  • 回顾字符串的定义方式

  • 了解转义字符

  • 字符串格式化的方法

  • 字符串相关函数

字符串的定义方式

  1. 单引号定义字符串 ‘ ’

  2. 双引号定义字符串 “ ”

  3. 三引号定义字符串 ‘’‘内容’‘’或者 “”“内容”“”

  4. 字符串定义时,引号可以互相嵌套

转义字符

一个普通的字符出现在转义符\的后面时,实现了另外一种意义。


  • \ 转义符,续行符。


作为转义符时,在\后面出现的字符可能会实现另外一种意义。


作为续行符时,在行尾使用了\后,可以换行继续书写内容。


str = '123'\    '456'print(str)
---123456
复制代码


打印结果看,并未换行,说明续行符起作用了。


  • \n 代表一个换行符


str = "岁月是一把杀猪刀, \n但是它拿长得丑的人一点办法都没有。"print(str)
---岁月是一把杀猪刀, 但是它拿长得丑的人一点办法都没有。
复制代码


  • \r代表光标位置(从\r出现的位置开始作为光标的起点)


str = "岁月是一把杀猪刀, \r但是它拿长得丑的人一点办法都没有。"print(str)
---但是它拿长得丑的人一点办法都没有。
复制代码


  • \t代表一个水平制表符(table 缩进)


str = "岁月是一把杀猪刀\t但是它拿长得丑的人一点办法都没有。"print(str)
---岁月是一把杀猪刀 但是它拿长得丑的人一点办法都没有。
复制代码


  • \b 代表一个退格符


str = "岁月是一把杀猪刀\b但是它拿长得丑的人一点办法都没有。"print(str)
---岁月是一把杀猪但是它拿长得丑的人一点办法都没有。
复制代码


注意看,并不是毫无改变的打印出来了,整句话中\b前面的这个字被退格了。


  • \\ 反转义\,输出了\,取消\的转义效果


str = "岁月是一把杀猪刀\\n但是它拿长得丑的人一点办法都没有。"print(str)
---岁月是一把杀猪刀\n但是它拿长得丑的人一点办法都没有。
复制代码


第二个\被前面的\转义了,所以n就不会再被转义,也就没有换行。


  • r, 如果我们想把转义字符也作为普通字符输出,那我们可以在字符串的最前面加上r


str = r"岁月是一把杀猪刀\n但是它拿长得丑的人一点办法都没有。"print(str)
---岁月是一把杀猪刀\n但是它拿长得丑的人一点办法都没有。
复制代码


字符串内的转移字符\n被打印了出来。

字符串相关的操作

  • 字符串+操作, 将参与运算的字符串相加后组成一个新的字符串。


str="君不见,黄河之水天上来,奔流到海不复回。"str2 = "君不见,高堂明镜悲白发,朝如青丝暮成雪。"res = '将进酒\n'+ str + '\n' + str2print(res)
---将进酒君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪。
复制代码


  • 字符串*操作,str*n就是 将当前字符串重复n


str = '重要的话说三遍\n' * 3print(str)
---重要的话说三遍重要的话说三遍重要的话说三遍
复制代码


  • 字符串[]切片操作


字符串的索引操作,字符串中只能使用[]下标访问,不能修改。


str[start:stop:step]功能,获取str的特定下标或者对str进行切片操作参数:  start: 可选,开始值,默认为0  stop: 可选,结束值,默认为len(str)  step:可选,步进值,默认为1
复制代码


因为所有参数都是可选项,所以其实我们可以什么参数都不给,直接使用默认值:


str = '凡诗之所谓风者,多出于里巷歌谣之作,所谓男女相与咏歌,各言其情者也。'print(str)# 等同于print(str[::])
---凡诗之所谓风者,多出于里巷歌谣之作,所谓男女相与咏歌,各言其情者也。凡诗之所谓风者,多出于里巷歌谣之作,所谓男女相与咏歌,各言其情者也。
复制代码


当我们写一个值,那就是获取指定下标的元素:


print(str[6])
---
复制代码


但是当我们只写一个值,并且后面跟上符号::, 那含义就是从start开始,向后取完:


print(str[6::])
---者,多出于里巷歌谣之作,所谓男女相与咏歌,各言其情者也。
复制代码


从这我们可以看出来,当我们只写一个单独的值而没有加::的时候,含义就是从start开始,但是并不向后继续取值,而有了::就是继续向后取值。其实,只写一个:也是一样的,因为只要知道向后取值,step默认值就是为1:


print(str[6:])
---者,多出于里巷歌谣之作,所谓男女相与咏歌,各言其情者也。
复制代码


那如果我们在这个基础上加上一个值,那就是从start开始直到stop之前。和range()一样,取不到stop


print(str[2:6])
---之所谓风
复制代码


然后再多加一个值,和range()一样,就是往后数step个数再取值:


print(str[2:15:2])
---之谓者多于巷谣
复制代码


其实,这里比较饶的并不是如何取值,二是::这两个符号。当我们将上面讲的这些内容了解通透后,就可以玩转字符串的切片了。


那对应的,如果我们想将字符串完全取值,但是是隔一个取一个,那我们就可以使用startstop的默认值,而只定义step


print(str[::2])
---凡之谓者多于巷谣作所男相咏,言情也
复制代码


那如果我们想让整个字符串倒过来呢?


print(str[::-1])
---。也者情其言各,歌咏与相女男谓所,作之谣歌巷里于出多,者风谓所之诗凡
复制代码

字符串的格式化方法

常用的字符串的格式化方法就是format()


先让我们看看最普通的方式:


s = '茶桁'str = '乘舟将欲行,忽闻岸上踏歌声。'
复制代码


我定义了这两个字符串,现在我想将两段字符串合在一起变成一句“茶桁乘舟将欲行,忽闻岸上踏歌声。”(嗯,权吾乃青蓮居士。)


很多小伙伴是不是觉得太简单了,我们之前学了+号,直接拼接不就好了。自然也是可以的,只是我们现在要用更普遍和便捷的方式来完成:


s = '茶桁'str = '{}乘舟将欲行,忽闻岸上踏歌声。'.format(s)print(str)
---茶桁乘舟将欲行,忽闻岸上踏歌声。
复制代码


假如说,我们现在只有诗词的大半句,其中少了踏歌行这三个字,那我们又该如何?那我们就往format中传入两个参数,后面那个参数自定义出这三个字符就可以了:


s = '茶桁'str = '{}乘舟将欲行,忽闻岸上{}。'.format(s, "踏歌行")print(str)
---茶桁乘舟将欲行,忽闻岸上踏歌行。
复制代码


看到这里,我们是不是认为字符串使用format就只能顺序传值?第一个答案填入第一个空,第二个答案填入第二个空... 其实不只是如此,字符串后使用format,其中的{}还可以接受索引传参:


s = '茶桁'str = '{1}乘舟将欲行,忽闻岸上{0}。'.format("踏歌行", s)print(str)
---茶桁乘舟将欲行,忽闻岸上踏歌行。
复制代码


通过索引传参的适用范围毕竟还是有限,我们很容易一不小心就会把参数顺序搞乱。那还有没有其他办法呢?


我们还可以通过关键字传参:


str = '{s2}乘舟将欲行,忽闻岸上{s1}。'.format(s1 = "踏歌行", s2 = "茶桁")print(str)
---茶桁乘舟将欲行,忽闻岸上踏歌行。
复制代码


那假如说我们得到的是一个列表数据,是否需要先转换数据?其实也没必要,format支持对容器型数据的传参数:


str = '豪放派:{0[0]},婉约派:{0[1]},流氓派:{0[3]},蛋黄派:{0[2]}'.format(['李白','辛弃疾','达利园','茶桁'])print(str)
---豪放派:李白,婉约派:辛弃疾,流氓派:茶桁,蛋黄派:达利园
复制代码


那么如果是字典类型的呢?那就更简单了,我们之前提到的关键字传参,不就正好对应字典吗?


dict = {'a':'茶桁', 'b':'蛋黄派'}str = '{a}乘舟将欲行,忽闻岸上{b}'.format(**dict)print(str)
---茶桁乘舟将欲行,忽闻岸上蛋黄派
复制代码


嗯,不错。似乎我们创建了一句新的诗句。


其实,format还有其他的用法,就是直接用关键字f, 比如:


str = f'{dict["a"]}乘舟将欲行,忽闻岸上{dict["b"]}'print(str)
---茶桁乘舟将欲行,忽闻岸上蛋黄派
复制代码


f是在 3.7 版本中新增的格式化方法,在使用的过程中,要注意字符串符号“”‘’的嵌套关系。


在基本使用之外,我们还有一些风骚的特殊用法,比如,我们可以用format直接限定小数的位数:


str = '圆周率是多少:{:.5f}'.format(3.1415926)print(str)
---圆周率是多少:3.14159
复制代码

字符串相关函数

在 Python 中,字符串应该是最常见的数据类型,对应字符串的函数也有不少。大家可以去看看官方的文档

英文字符与字符检测相关函数

我们可以返回字符串的副本,并且将首字母大写,其余小写:


str = 'I am a data product manager'str.capitalize()
---'I am a data product manager'
复制代码


因为我在使用 Jupyter Notebook,所以即便我么有使用print,依然可以打印出执行结果。只是仅可以打印最后一个执行的函数。


可以把字符串中的一个单词的首字母大写:


str.title()
---'I Am A Data Product Manager'
复制代码


可以全部改为大写:


str.upper()
---'I AM A DATA PRODUCT MANAGER'
复制代码


把字符串全部改为小写


str.lower()
---'i am a data product manager'
复制代码


字符串中的大小写字符转换,大写转小写,小写转大写:


str.swapcase()
---'i AM A DATA PRODUCT MANAGER'
复制代码


检测字符是否包含在字符串内:


print('o' in 'love')
---True
复制代码


检测字符串是否为全部大写字母组成


str.isupper()
---False
复制代码


检测字符串是否为全部小写字母组成


str.islower()
---False
复制代码


检测字符串是否符合标题title的要求


str.istitle()
---False
复制代码


检测字符串是否由数字和字母组成,如果字符串中包含来非数字字母的其它字符,则返回 False


str.isalnum()
---False
复制代码


检测字符串是否全部由字符(包含英文字符和中文)组成


str.isalpha()
---False
复制代码


检测字符串是否由纯数字字符组成


'123'.isdigit()
---True
复制代码


检测当前字符串是否为 空格 字符组成 ' ’


' '.isspace()
---True
复制代码


检测字符串是否以指定的字符开始的,也可以指定开始和结束的位置


str.startswith('I')
---True
复制代码


str.startswith('a', 5)
---True
复制代码


检测字符串是否以 指定的字符 结束的,也可以指定开始和结束的位置


print(str.endswith('a'))print(str.endswith('a', 5, 11))print(str.endswith('a', 1, 6))
---FalseTrueTrue
复制代码

字符串的查找和操作相关函数(✨ 重点)

前面铺垫了那么多之后,接下来这部分,才是这一节的重点。


让我们先从查找来看:


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


find会返回一个子字符串,找到字符中符合条件的第一个字符出现的索引位置,未找到则返回-1


str = "I am a data product manager."print(str.find('am'))
---2
复制代码


让我们用切片的方式反过来找一下看看:


res = str.find('am')str[res:res+2]
---'am'
复制代码


我们从之前可以知道res取值为2,现在等于是str[2:4], 正好是am所在的位置。


find中有startend,是支持切片查找的:


print(str.find('am', 0, 4))print(str.find('am', 4, 10))
---2-1
复制代码


可以看到,在从 4 开始找到 10 的时候找不到am, find有一个功能相同,但是方向不同的方法rfind(), 和find的不同点只是,rfind是从后往前找的。


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


类似于find(), 但在找不到子字符串的时候会引发ValueError


str.index('python')
---ValueError: substring not found
复制代码


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


这个函数会在字符串中去查找sub在其中[start, end]范围内非重叠出现的次数。


print(str.count('a'))print(str.count('a', 5, 12))
---63
复制代码


接下来让我们看看字符串操作相关的函数:


str.split(sep=None, maxsplit=-1)


这个方法可以按照指定的分隔符(sep),把字符串分隔成列表。


str = 'user_admin_id_123'str.split('_')
---['user', 'admin', 'id', '123']
复制代码


整个方法里的maxsplit是进行多少次拆分,比如1为一次拆分,也就是会返回 2 个元素。默认值为-1,意思是不限制拆分次数。


str.split('_', 1)
---['user', 'admin_id_123']
复制代码


str.rsplit(sep=None, maxsplit=-1)


split方法相似,只是方向不同。这个是从后向前获取。


str.rsplit('_')
---['user', 'admin', 'id', '123']
复制代码


这段代码可以看到功能上是完全一样的,如果我们把maxsplit加进去,就能看到方向上的不同:


str.rsplit('_', 1)
---['user_admin_id', '123']
复制代码


这样就能清晰看到,rsplit是从后面开始拆分的。


str.join(iterable)


join的功能和split可以看成是相反的,是使用指定的字符串,把一个容器中的元素连接成一整个字符串


str = ['user', 'admin', 'id', '123']'_'.join(str)
---'user_admin_id_123'
复制代码


str.strip([chars])


去除字符串左右两侧的指定字符, chars参数为置顶要溢出字符的字符串,默认移除空白符。


str = ' chaheng 'str.strip(' ')
---'chaheng'
复制代码


这个函数有两个伴生函数,一个是rstrip, 从方法名应该能猜的出来,这是去掉字符串右侧的指定字符,另一个是lstrip, 这是去除左侧的指定字符。


str.rstrip(' ')str.lstrip(' ')
---' chaheng''chaheng '
复制代码


len()函数可以获取当前字符串的长度


len(str)
---9
复制代码


str.replace(old, new[, count])


可以替换对应的字符串,将old都替称为newcount则是替换次数。比如一个字符串内出现了十次old, 我``count给的5, 则只替换前5次出现的old`字符串。


str = 'abcabcabcabcabcabc'str.replace('a', 'e')str.replace('a', 'e', 2)
---'ebcebcebcebcebcebc''ebcebcabcabcabcabc'
复制代码


可以注意一下两次打印的区别。


这次就不留练习题了,字符串的查询和操作函数属于重中之重,大家最好是多去练习几遍,将其中的方法记会杯熟。


好,今天就到这里。咱们下节课再见。

发布于: 刚刚阅读数: 4
用户头像

茶桁

关注

还未添加个人签名 2020-10-20 加入

还未添加个人简介

评论

发布
暂无评论
8. 字符串详解_Python_茶桁_InfoQ写作社区