一、字符串是什么?
- 字符串是容器型数据类型,可以同时存储多个文字符号;不同于列表、字典、元组,字符串存储的数据会被计算机默认为是文字符号。将’单引号’、“双引号”、‘’‘三引号’''作为容器的标志,里面的每一个符号都是字符串的元素。
- 字符串是不可变的数据类型,不支持增删改;字符串是有序的,支持索引操作。
- 字符串的元素: 字符串每一个独立的符号,又叫字符;任何文字符号都可以作为字符串的元素(中文、英文、标点符号、表情符号等)
- 就基本上只要你见过的符号,文字,网上所有的可是化信息,你能用键盘打印出来或者复制粘贴过来都可以算字符
- 注释:三个引号开头和结束的内容可能是字符串也可能是注释。只有这个内容放在特点位置的时候才是真正意义上的注释(文件开头、函数开头、类开头),其中还有个简单的区分方法就是看pycharm上面的颜色,字符串和注释的颜色是不一样的。
- 字符串是可以比较大小的
二、字符分类
1.普通字符
- 在字符串中表示符号本身的字符就是普通字符。
str2 = "hello"
print(str2)
# hello
# 这种打印出来就是它本身的字符就是普通字符
2.转义字符
- 转义字符: 在特定的符号前加 \ 来表示特殊功能或者特殊字符的字符,python本身是没有转义字符的,但是C语言有,而python是基于C写的,所以有些转义字符留了下来,以下介绍一下常用的几种
1.\n - 换行
# 先打印abc然后换行打印10
str1 = 'abc\n10'
print(str1)
# abc
# 10
2.\t - 水平制表符(按一个tab)
# 先按tab打印123然后换行打印abc
str1 = '\t123\nabc'
print(str1)
# 123
# abc
3. \’ - 表示一个普通的单引号
str1 = 'it\'s OK'
print(str1)
# it's OK
4.\" - 表示一个普通的双引号
str1 = "I say:\"good good study, day day up\""
print(str1)
# I say:"good good study, day day up"
5. \\ - 表示一个普通的反斜杠
# 有些时候我们在读取文件时用单引号可能会报错因为有转义符的存在
path = 'c:\admin\name\test\demo\a.txt'
print(path)
# c:dmin
# ame est\demo.txt
path = 'c:\\admin\\name\\test\\demo\\a.txt'
print(path)
# c:\admin\name\test\demo\a.txt
6. r/R字符串
- 在字符串引号的前面加 r 或者 R,可以让字符串中所有的转义字符功能消失变成普通字符
str1 = r'\tabc\n123'
print(str1)
# \tabc\n123
三、字符编码
1.介绍
- 计算机在存储数据的时候只能存数字。
- 字符编码是一种将字符映射到数字的方法,以便计算机能够处理和存储文本数据。
- 为了能够让计算机存储文字符号,我们给每一个文字符号绑定一个固定的数字,每次在需要存这个符号的时候就去存这个数字。跟文字符号绑定的数字就是这个符号的编码值。
- 总的来说,字符编码是一种将文本转换为计算机可以理解和处理的数字表示的方法,不同的编码标准支持不同的字符集和语言。
2.ASCII码表和Unicode编码表
- ASCII码表是美国信息交换标准代码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准 ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符
- 统一码(Unicode),也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。统一码是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
3.编码在python中的应用
1.chr(编码值) - 获取编码值对应的字符
print(chr(97))
# a
2.ord(字符) - 获取字符对应的编码值
print(ord('是'), ord('靖'),ord('不'),ord('是'),ord('静'))
# 26159 38742 19981 26159 38745
3.中文编码的范围:4e00~9fa5
# 打印所有的中文字符,并统计个数
num = 0
for x in range(0x4e00, 0x9fa5+1):
print(chr(x), end=' ')
num += 1
print('个数:', num)
# 20902 因为打印出来太多就说一下总共的个数,感兴趣的小伙伴可以自己试一下
4.如何获取编码字符,并判断一个字符是否为中文
- python中所有的字符都有两种表示方式:a.直接写符号本身 b.写对应的编码字符
- 编码字符: \u + (4位的16进制的字符编码值)
- 判断x是否是中文: ‘\u4e00’ <= x <= ‘\u9fa5’
# 如何获得一个字符的编码字符
str2 = '靖\u9756'
# 先获取文字的对应的编码值
print(ord('靖')) # 38742
# hex()函数是用来计算16进制数的
print(hex(38742)) # 0x9756
# 0x9756 0x前缀表示是16进制数,取后四位
print(str2)
# 靖靖
# 用以上方法可以获取到中文的第一到最后的编码字符
# 判断一个符号是否是汉字:
x = '靖'
print('\u4e00' <= x <= '\u9fa5')
# True
四、字符串的操作
1.查操作
- 字符串支持下标索引查找的操作,也支持切片的操作获取元素。下标不能越界,不然会报错。
# 下标索引
str1 = '是靖不是静'
print(str1[0],str1[-1])
# 是 静
# 切片
print(str1[::-1])
# 静是不靖是
print(str1[:3])
# 是靖不
print(str1[3::-1])
# 是不靖是
2.字符串比较大小
1.字符串之间如何比较大小
- 因为编码值的存在所以字符串也是可以比较大小的
- 如果有多个字符,就比较第一对不同字符的大小
- 注意,空格也是有编码值的而且会参与比较大小的计算
- 大写和小写的英语字母编码值也是不一样,小写的字母比大写的大
print(ord('a'), ord('A'))
print('a' > 'A')
# 97 > 65
# True
print(ord('b'),ord(' '))
print('ab' > 'a ')
# 因为a是一样的,所以比较第二个字符的大小
# 98 > 32
# True
2.判断x是否是数字字符: ‘0’ <= x <= ‘9’
x = '33'
print('0' <= x <= '9')
# True
3.判断x是否是小写字母: ‘a’ <= x <= ‘z’
x = 'b'
print('a' <= x <= 'z')
# True
4.判断x是否是大写字母: ‘A’ <= x <= ‘Z’
x = 'G'
print('A' <= x <= 'Z')
# True
5.判断x是否是字母: ‘a’ <= x <= ‘z’ or ‘A’ <= x <= ‘Z’
x = 't'
print('a' <= x <= 'z' or 'A' <= x <= 'Z')
# True
3.字符的数学运算(+和*)
- 字符串的加法操作可以实现多个字符串拼接
- 字符串的乘法操作可以实现重复字符串
str1 = '是靖'
str2 = '不是'
str3 = '静'
print(str1 + str2 + str3)
# 是靖不是静
str1 = '是靖'
str2 = '不是'
str3 = '静'
print(str1*2 + str2*2 + str3*2)
# 是靖是靖不是不是静静
4. 字符串的增删改
- 因为字符串是不可变的数据类型,所以不支持直接增删改的操作,但是我们利用数学运算来实现其效果。
# 增:在str1中所有的数字字符后面添加一个?
str1 = '和23开始的skj02=。shs81sh蛇女'
# 创建一个空字符串
new_str1 = ''
for x in str1:
# 判断str1字符串中的元素是否是数字字符,如果是就添加进新的字符串并且加一个?
if '0' <= x <= '9':
new_str1 += x + '?'
# 否则只添加元素
else:
new_str1 += x
print(new_str1)
# 和2?3?开始的skj0?2?=。shs8?1?sh蛇女
# 改:将str1中所有的数字字符改成*
str1 = '和23开始的skj02=。shs81sh蛇女'
# '和**开始的skj**=。shs**sh蛇女'
new_str1 = ''
for x in str1:
if '0' <= x <= '9':
new_str1 += '*'
else:
new_str1 += x
print(new_str1)
# 和**开始的skj**=。shs**sh蛇女
# 删:将str1中所有的数字字符全部删除
str1 = '和23开始的skj02=。shs81sh蛇女'
# '和**开始的skj**=。shs**sh蛇女'
new_str1 = ''
for x in str1:
if '0' <= x <= '9':
pass
else:
new_str1 += x
print(new_str1)
# 和开始的skj=。shssh蛇女
5. 字符串的相关函数
1.max、min、sorted、len等函数
- 字符串也可以使用max、min、sorted、len等函数,因为有编码值的存在,但是一般不会用,因为字符串求最大值和排序没有什么实际的意义,其中注意使用len函数时,转义字符的长度为1
str1 = '\tabc\n123\u4e98'
print(len(str1))
# 9
# max、min
str1 = '是靖不是静'
print(max(str1))
# 静
print(min(str1))
# 不
# sorted
print(sorted(str1))
# ['不', '是', '是', '靖', '静']
# 返回列表
2.str
- str(数据) - 将指定数据转换成字符串。(任何数据都可以转换成字符串;转换的时候在数据的打印值外面加引号)
A1 = str(100) # '100'
A2 = str(1.23) # '1.23'
A3 = str(True) # 'True'
A4 = str([100, 'abc', True]) # "[100, 'abc', True]"
print(type(A1), type(A2), type(A3), type(A4))
# <class 'str'> <class 'str'> <class 'str'> <class 'str'>
3.eval
- eval(字符串) - 去掉字符串最外面的引号,获取字符串内容的结果
- 使用要求:字符串掉引号以后必须是一个合法表达式
r1 = eval('100')
print(r1, type(r1)) # 100 <class 'int'>
r2 = eval('1.23')
print(r2, type(r2)) # 1.23 <class 'float'>
r3 = eval('True')
print(r3, type(r3)) # True <class 'bool'>
str1 = "{'a': 10, 'b': 20, 'c': 30}"
print(eval(str1)) # {'a': 10, 'b': 20, 'c': 30}
- eval是个很强大的函数,只要你能把一个程序的表达式写出来,它就可以直接让程序运行,就比如一百以内的累加和,一般就是定义一个变量等于0,然后用循环累加,如果用eval一句代码就可以搞定。
# '1+2+3+...+100'
str1 = '+'.join(str(x) for x in range(1, 101))
print(eval(str1))
# 5050
五、字符串的相关方法
1.用指定元素连接字符串(join)
- ‘指定字符串’.join(容器) - 将容器中的元素用指定的字符串连接成一个新的字符串
- 容器的要求:容器中的元素必须全部都是字符串
fruits = ['苹果', '香蕉', '葡萄']
result = 'and'.join(fruits)
print(result)
# '苹果and香蕉and葡萄'
# 指定的字符串里面可有多个字符
result = '+8+'.join('abc')
print(result)
# a+8+b+8+c
# 练习:使用join方法创建'2+4+6+...+100'并计算和
result = '+'.join([str(x) for x in range(2, 101, 2)])
print(eval(result))
# 2550
2.字符串切割(split)
- 字符串1.split(字符串2) - 将字符串1中所有的字符串2作为切割点对字符串1进行切割
str1 = 'abcmn123mnabcmn你好mnkl'
result = str1.split('mn')
print(result)
# ['abc', '123', 'abc', '你好', 'kl']
str2 = '⻉⻉,花花,财财,包⼦,可乐,旺财'
result = str2.split(',')
print(result)
# ['⻉⻉', '花花', '财财', '包⼦', '可乐', '旺财']
- 注意返回类型是列表
- 切割字符串的时候如果切割点在字符串开头或者字符串结尾或者切割点连续出现切割后都会出现空串
str2 = ',⻉⻉,花花,财财,包⼦,,可乐,旺财,'
print(str2.split(','))
# ['', '⻉⻉', '花花', '财财', '包⼦', '', '可乐', '旺财', '']
- 字符串1.split(字符串2,N) - 将字符串1中前N个字符串2作为切割点对字符串1进行切割
str1 = 'abcmn123mnabcmn你好mnkl'
result = str1.split('mn', 2)
# 只切割前两个mn,后面的不切割
print(result)
# ['abc', '123', 'abcmn你好mnkl']
3. 字符串替换(replace)
- 字符串1.replace(字符串2, 字符串3) - 将字符串1中所有的字符串2都替换成字符串3
str2 = '⻉⻉,花花,财财,包⼦,可乐,旺财'
result = str2.replace(',', '=')
print(result)
# ⻉⻉=花花=财财=包⼦=可乐=旺财
str1 = '是靖不是静'
result = str1.replace('靖', '敬')
print(result)
# 是敬不是静
- 字符串1.replace(字符串2, 字符串3,N) - 将字符串1中前N个字符串2都替换成字符串3
str1 = '是靖,是靖,是靖,是靖,不是静'
result = str1.replace('靖', '敬', 2)
print(result)
# 是敬,是敬,是靖,是靖,不是静
- 空格也可以替换
str1 = '是 靖 不 是 静'
result = str1.replace(' ', '')
print(result)
# 是靖不是静
4. 字符串两边空白的消除(strip)
- 字符串.strip() - 去掉字符串两边的空白字符(空白包括:空格、换行和水平制表符)
str1 = """
是靖不是静
"""
print(str1.strip())
# 是靖不是静
str2 = '\n\t abc\n '
print(str2.strip())
# abc
5.查找指定字符串(find和index)
- 字符串1.find(字符串2) - 查找字符串2在字符串1中第一次出现的位置,如果找不到返回-1
str1 = '是靖不是静'
print(str1.find('静'))
# 4
print(str1.find('敬'))
# -1
- 字符串1.find(字符串2, 开始下标, 结束下标) - 获取字符串2在指定范围内第一次出现的位置
- 字符串1.rfind(字符串2) - 从后往前找,同时也是可以指定范围找
str1 = '是静,不是靖,是静,不是靖,不是静'
# 从前往后找第一个静的位置
print(str1.find('静'))
# 1
# 从前往后找5到16第一个静的位置
print(str1.find('静', 5, 16))
# 8
# 从后往前找第一个静的位置
print(str1.rfind('静', 0, 17))
# 16
- 字符串1.index(字符串2) - 查找字符串2在字符串1中第一次出现的位置,如果找不到程序报错
- index和find一样也可以指定范围找,也可以用rindex从后往前找。唯一区别就是一个找字符中没有的元素会报错,一个返回-1
str1 = '是靖不是静'
print(str1.index('静'))
# 4
print(str1.index('敬'))
# ValueError: substring not found
print(str1.index('静'))
# 1
print(str1.index('静', 5, 16))
# 8
print(str1.rindex('静', 0, 17))
# 16
6.替换字符串中不同的字符(maketrans和translate)
- 字符串.maketrans(字符串1, 字符串2) - 将字符串1和字符串2中相同位置上的字符作为对应关系创建一个对应关系表
- 字符串.translate(对应关系表) - 按照对应关系表将字符串中指定的字符进行替换
- 这两个方法一般是配合使用,因为对应关系表是编码值的对应关系表。
- maketrans里面的两个字符串内容长度必须一样,而且替换对应的位置也必须一致,字符串1里面的内容不能重复,因为是要被替换的元素,不可能一样的字符同时被替换成两种不同的字符,字符串2的字符可以重复
# 案例:将字符串中所有的数字字符都替换成对应中文数字
str1 = '191路公交车电话12453'
table = str.maketrans('0123456798', '零一二三四五六七九八')
print(table)
# 这就是编码值的对应表,因为现实中很难自己写,所以使用maketrans处理
# {48: 38646, 49: 19968, 50: 20108, 51: 19977, 52: 22235, 53: 20116, 54: 20845, 55: 19971, 57: 20061, 56: 20843}
result = str1.translate(table)
print(result)
# 一九一路公交车电话一二四五三
# 字符串1内容不可重复,字符串2可以
str1 = '是靖不是静'
table = str.maketrans('靖静', '敬敬')
result = str1.translate(table)
print(result)
# 是敬不是敬
7.统计字符串指定元素的个数
- count(str, beg= 0,end=len(string)) - 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
str1 = '是靖不是静,不是静,是靖,还是靖,也是静'
print(str1.count('是'))
# 6
# 指定范围内查找
print(str1.count('静', 5, len(str1)))
# 2
8.其他方法
- Python为字符串提供的方法差不多有四十多个,以上就讲一些常用的,还有很多比如转换大小写、判断有没有数字等,可以查看字符串方法
六、格式字符串
1.f-string
- 格式字符串的方法有很多,其中很多我已经在输出和输入函数时说过这次主要讲一下之前没写过的。
- f-string,亦称为格式化字符串常量(formatted string literals),是Python3.6新引入的一种字符串格式化方法,该方法源于PEP 498 – Literal String Interpolation,主要目的是使格式化字符串的操作更加简便。
- 基本用法:在字符串的前面加f或者F以后就可以在字符串中通过 {提供数据的表达式} 来提供字符串中的内容
# 假如我要输出一个“是靖不是静今年22岁!”
name = '是靖不是静'
age = 22
# 直接在里面用{变量名}就可以
message = f'{name}今年{age}岁!'
print(message)
# 是靖不是静今年22岁!
# 可以在里面进行计算
str1 = f'{name*2}今年{age+10}岁!'
print(str1)
# 是靖不是静是靖不是静今年32岁!
# 一定要加f不然没用
str1 = '{name*2}今年{age+10}岁!'
print(str1)
# {name*2}今年{age+10}岁!
2.添加参数: f’{提供数据的表达式: 参数}’
1.控制小数位数:f’{提供数据的表达式:.Nf}’
sal = 91820.9283
str1 = f'月薪:{sal:.2f}元'
print(str1)
# 月薪:91820.93元
2.让数字整数部分每三位一个逗号隔开:f’{提供数据的表达式:,}’
sal = 91820.9283
str1 = f'年薪:{sal*13:,}元'
print(str1)
# 年薪:1,193,672.0679元
# 可以和控制小数位数的参数一起使用
str2 = f'年薪:{sal*13:,.2f}元'
print(str2)
# 年薪:1,193,672.07元
3.显示百分比:f’{提供数据的表达式:.N%}’
sale = 0.5
str1 = f'市场占有率:{sale: .0%}'
print(str1)
# 市场占有率: 50%
# 如果没有.N就会输出六位的分数
sale = 0.5
str1 = f'市场占有率:{sale: %}'
print(str1)
# 市场占有率: 50.000000%
4.控制填空数据的长度
- f’{提供数据的表达式:符号>N}‘、f’{提供数据的表达式:符号<N}‘、f’{提供数据的表达式:符号^N}’
- 如果符号是空格,符号不写
- 数据长度为N,假如原始数据长度为M,如果是<符号,则将在数据左边写入(N-M)个指定的符号,相反是>的话就在右边写入,如果是^的话就在两边写,如果写入的符号数量是偶数就两边一样多,如果不是就左边比右边少一个。
x = '你好'
# 数据要是长度为5,你好有两个,要找一个字符去填剩下的3个空间
str1 = f'x:{x:+>5}'
print(str1)
# x:+++你好
x = '你好'
str1 = f'x:{x:-<5}'
print(str1)
# 你好---
x = '你好'
str1 = f'x:{x:*^5}'
print(str1)
# x:*你好**
七、字符串推导式
- 和列表相似,不同的是字符串推导式无法直接创建,需要先创建个空列表,然后使用 join 方法搭配在一起使用。
- 字符串推导式里面的数据必须是字符串
- 字符串.join(表达式 for 变量 in 容器)
str1 = ''
print(str1.join(i for i in ['是', '靖', '不', '是', '静']))
# 是靖不是静
- 推导式有个小技巧,可以创建一个有符号的列表,然后再用推导式,可以用符号把推导式里面的的内容连接起来。
- 字符串推导式也可以使用if判断语句,和列表使用方法一样
str2 = '+'
print(str2.join(str(i) for i in range(10) if i % 2 == 0))
# 0+2+4+6+8
- 这时如果我们再用上eval()函数,就可以一句语句实现0到9偶数的总和
print(eval(str2.join(str(i) for i in range(10) if i % 2 == 0)))
# 20
总结
字符串是不可变的数据类型,不支持增删改;字符串是有序的,支持索引操作。是我们常用的python数据类型,而且字符串是支持比较大小的,字符串的方法有40多个,是很灵活的数据类型,其次掌握好字符串的推导式可以简洁我们的很多python代码。