首页 > 技术文章 > Python字符串详解

jddreams 2018-11-26 15:55 原文

一、 字符串含义

在Python中字符串是以单引号'或双引号"括起来的由数字、字母或其他符号组合在一起的任意文本,比如'abc',"xyz"等等。

请注意:''或""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有 a,b,c 这 3 个字符。

二、转义符

1. 如果'本身也是一个字符,那就可以用""括起来。

"I'm OK"

包含的字符是I,',m,空格,O,K这 6 个字符。

2. 如果字符串内部既包含'又包含"可以用转义字符\来标识。

>>>print('I\'m \"OK\"!')
I'm "OK"!

转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\,可以在 Python 的交互式命令行用 print()打印字符串看看:

>>> print('I\'m ok.') 
I'm ok. 
>>> print('I\'m learning\nPython.') 
I'm learning 
Python. 
>>> print('\\\n\\') 
\ 
\ 

如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python 还允许用r''表示''内部的字符串默认不转义,可以自己试试:

>>> print('\\\t\\') 
\       \ 
>>> print(r'\\\t\\') 
\\\t\\ 

如果字符串内部有很多换行,用\n 写在一行里不好阅读,为了简化,Python 允许用'''...'''的格式表示多行内容,可以自己试试:

>>> print('''line1 
... line2 
... line3''') 
line1 
line2 
line3 

上面是在交互式命令行内输入,注意在输入多行内容时,提示符由>>>变为...,提示你可以接着上一行输入。如果写成程序,就是:

print('''line1 
line2 
line3''') 

多行字符串'''...'''还可以在前面加上 r 使用,请自行测试。

三、 字符串编码

在Python 3.x版本中,字符串是以Unicode编码的,也就是说,Python的字符串支持多语言。

对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:

#ord()和chr()
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'

如果知道字符的整数编码,还可以用十六进制这么写str:

# 十六进制——字符串编码
>>> '\u4e2d\u6587'
'中文'

由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。Python对bytes类型的数据用带b前缀的单引号或双引号表示:

# Bytes编码
>>>s = b'ACV'
>>>print(s)
b'ACV'
>>>s
b'ACV'

要注意区分'ABC'和b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字符都只占用一个字节。

以Unicode表示的str通过encode()方法可以编码为指定的bytes,例如:

# 字符串编码之ASCII、UTF-8
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

需要注意的是,我们可以将str转换成任意编码的bytes。但是在转换含有中文的str时,不能转换成ascii编码的bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:

#decode()用法
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

四、 字符串常用方法

1. 字符串运算

Pyhon用“+”来合并拼接字符串。

>>>x = "Hello,"
>>>y = 'world!'
>>>x + y
'Hello,world!'
>>>print(x + y)
Hello,world!
运算符 Python 表达式 结果 描述 支持的数据类型
+ [1, 2] + [3, 4] [1, 2, 3, 4] 合并 字符串、列表、元组
* ["Hi!"] * 4 ['Hi!', 'Hi!', 'Hi!', 'Hi!'] 重复 字符串、列表、元组
in 3 in (1, 2, 3) True 元素是否存在 字符串、列表、元组、字典
not in 4 not in (1, 2, 3) True 元素是否不存在 字符串、列表、元组、字典
> >= == < <= (1, 2, 3) < (2, 2, 3) True 元素比较 字符串、列表、元组
注意:\
in 在对 字典 操作时,判断的是 字典的键\
in 和 not in 被称为 成员运算符

2. 字符串格式化

我们经常会输出类似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'之类的字符串,而xxx的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式。

c语言中可以采用%来控制输出的格式,python中也类似。示例代码如下:

# 字符串格式化(%)
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('James', 1000000)
'Hi, Michael, you have $1000000.'

2.1 百分号方式

%运算符就是用来格式化字符串的。

在字符串内部,%s表示用字符串替换,%d表示用整数替换,%f表示用浮点数替换,%x表示用十六进制证书替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。如果你不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串:遇到字符串本身含有%,怎么办呢?这个简单,这要转义就OK拉。用%%来表示一个%

# %转义
>>> 'growth rate: %d %%' % 7
growth rate: 7 %

格式化代码及意义:

代码 意义
s 字符串,使用str
r 字符串,使用repr不使用str
c 字符
d 十进制的数字
i 整数
u 无符号整数
o 八进制
x 十六进制
X 大写十六进制
e 浮点指数
E 大写浮点指数
f 十进制浮点
F 大写十进制浮点
g 浮点e或者f
G 浮点E或者F
>>>tpl = "i am %s" % "xhg"
>>>print(tpl)
i am xhg

>>>tp2 = "i am %s, i am from %s" % ("xhg","China")
>>>print(tp2)
i am xhg, i am from China

>>>tpl = "i am %(name)s age %(age)d" % {"name": "xhg", "age": 18}
>>>print(tpl)
i am xhg age 18

>>>tpl = "percent %.2f" % 99.97623
>>>print(tpl)
percent 99.98

>>>tpl = "i am %(pp).2f" % {"pp": 123.425556, }
>>>print(tpl)
i am 123.43

# 当字符串中存在格式化标志时,需要用 %%表示一个百分号
>>>tpl = "i am %(pp).2f %%" % {"pp": 123.425556, }
>>>print(tpl)
i am 123.43 %

2.2 Format方式

[[fill]align][sign][#][0][width][,][.precision][type]
  • fill 【可选】空白处填充的字符
  • align 【可选】对齐方式(需配合width使用)
    • <,内容左对齐
    • >,内容右对齐(默认)
    • =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
    • ^,内容居中<br>
  • sign 【可选】有无符号数字
    • +,正号加正,负号加负;
    • -,正号不变,负号加负;
    • 空格 ,正号空格,负号加负;
  • # 【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
  • , 【可选】为数字添加分隔符,如:1,000,000
  • width 【可选】格式化位所占宽度
  • .precision 【可选】小数位保留精度
  • type 【可选】格式化类型
    • 传入” 字符串类型 “的参数
      • s,格式化字符串类型数据
      • 空白,未指定类型,则默认是None,同s
    • 传入“ 整数类型 ”的参数
      • b,将10进制整数自动转换成2进制表示然后格式化
      • c,将10进制整数自动转换为其对应的unicode字符
      • d,十进制整数
      • o,将10进制整数自动转换成8进制表示然后格式化;
      • x,将10进制整数自动转换成16进制表示然后格式化(小写x)
      • X,将10进制整数自动转换成16进制表示然后格式化(大写X)
    • 传入“ 浮点型或小数类型 ”的参数
      • e, 转换为科学计数法(小写e)表示,然后格式化;
      • E, 转换为科学计数法(大写E)表示,然后格式化;
      • f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
      • F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
      • g, 自动在e和f中切换
      • G, 自动在E和F中切换
      • %,显示百分比(默认显示小数点后6位)

format经常用法:

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

# 定义一个坐标值
c = (250, 250)
s2 = "敌人坐标:{}".format(c)

# 通过位置
>>> data = ["djb", 18]
>>> "Name:{0}, Age:{1}".format(*data)
Name:djb, Age:18

# 通过关键字
>>> data = {"name": "djb", "age": 18}
>>> "Name:{name}, Age:{age}".format(**data)
Name:djb, Age:18

# 精度与类型f
>>> "{:.2f}".format(3.1415926)
3.14

# 通过下标
>>> "{0[0]} is {0[1]} years old.".format(data)
djb is 18 years old.

# 填充与对齐
# 填充常跟对齐一起使用
# ^、<、>分别是居中、左对齐、右对齐,后面带宽度
# :号后面带填充的字符,只能是一个字符,不指定的话默认是用空格填充。
>>> "{:>10}".format('18')
        18
>>> "{:0>10}".format('18')
0000000018
>>> "{:A>10}".format('18')
AAAAAAAA18

# 补充一个字符串自带的zfill()方法:
# Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0。
# zfill()方法语法:str.zfill(width)
# 参数width指定字符串的长度。原字符串右对齐,前面填充0。
# 返回指定长度的字符串。
>>> "18".zfill(10)
0000000018

3. 字符串长度

要计算str包含多少个字符,可以用len()函数。

>>> len('ABC')
3
>>> len('中文')
2

如果换成bytes,len()函数就计算字节数:

>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6

在操作字符串时,我们经常遇到str和bytes的互相转换。特别地,为了避免乱码问题,应当始终坚持使用UTF-8编码对str和bytes进行转换。

4. 字符串切片

s31 = s.split(str, maxsplit)

# 以str为分隔符 切片mystr,如果maxsplit有指定值,则仅分割为maxsplit个子字符串。返回的是一个包含子字符串的列表。
s = ' qwer12 345 @#$%^ '
#字符串分割,将s字符串按1分割为列表,返一个列表,不包括分割的字符,s1 = [' qwer', '2 345 @#$%^ '],
s1 = s.split('1')

s = 'qwerty*'  #定义字符串
#字符串索引值从0开始,s = [start:end:step]  取值规律:顾头不顾尾巴

s1 = s[:]        #全取,相当于s1 = s,s1 =  qwerty*
s2 = s[0:]       #从0去到最后,也相当于全取值,s1 =  qwerty*
s3 = s[:5]       #取到第五个,但是不包括第五个,实际取到第四个,[)前开后闭,s3 =  qwert
s4 = s[2:5]      #取第二个到第四个,s4 =  ert
s5 = s[2:]       #从第二个取到结束,s5 =  erty*
s6 = s[:-1]      #开始取到倒数第二个,即出去最后一个全取,s6 =  qwerty
s7 = s[1:-1:2]   #第一个取到倒数第一个,不包括倒数第一个,2为步长,隔一个取一个,s7 =  wry

5. 遍历每个字符

s = 'qwertyuiop456789@#$%^&*'#定义字符串
li = []  #定义空列表存储遍历的值
for i in s:
    li.append(i)  #值遍历值加入li列表
#打印列表
print(li)

打印li列表值结果如下:

['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '4', '5', '6', '7', '8', '9', '@', '#', '$', '%', '^', '&', '*']

6. 删除空格

#去除字符串左右两边的空格与回车,注:中间不能去除
s4 = s.strip()

#去掉右边的空格与回车
s5 = s.rstrip()

#去掉左边的的空格与回
s6 = s.lstrip()

7. 大小写转换

s61 = s.lower()               #转换为小写
s62 = s.upper()               #转换为大写
s63 = s.swapcase()            #大小写互换
s = 'hello every in my mind'
s64 = s.title()               #将每个字符串的首字母转换为首字母大写,s64 = Hello Every In My Mind
s65 = s.capitalize()          #字符串首字母大写,s65 = Hello every in my mind

8. 判断字符串类型

#是否是系列,返回Ture或False
s71 = s.isdigit()       #是否是数字
s72 = s.isalnum()       #是否是字母或数字
s73 = s.isalpha()       #是否是字母
s74 = s.isupper()       #是否是大写字母
s75 = s.islower()       #是否是小写字母
s76 = s.isspace()       #是否是空格
s77 = s.istitle()       #是否是标题格式(每个英文首字母大写)

9. 查找替换

# 查找

S81.find(str, start, end)

# 检测str是否包含在mystr中,如果是则返回开始值的索引,否则返回 -1。
# 注意:
# 如果未指明起始索引start和结束索引end,默认是从0到最后。
# 未指明起始索引start跟结束索引end, 且str是存在于mystr中。
# 指明起始索引跟结束索引,且str不在mystr[0:10]中出现。即str不存在。

s82.index(str, start, end)

# 跟find() 用法一样,但是 str如果不在mystr里面则会包一个错误,而不是 -1。
# 注意:
# 如果未指明start和end索引值,则默认是从0到最后。

# 统计次数

s83 = s.count(str, start, end)

# 返回str在索引start到end之间  在s中出现的次数。
# 注意:
#如果不写start和end则默认索引是从0到最后。也可以自己指定起始索引或结束索引。如果str不在s中则返回的值是0,而不会报错。

# 替换

s84 = s.replace(str1, str2, mystr.count(str1))

# 把s中的 str1 替换成 str2,如果count指定, 则不超过count次数。
# 注意:
# s.count(str1)即 count次数, 可以自己任意指定。如果未指定则默认是将s中 只要出现的str1 都会替换成 str2。

10. 其它


s16 = s.center(40,'*')       #打印输出字符,让字符串放在中间,s16 = *********** qwer12 345 @#$%^ ***********
s21 = s.rjust(40,'*')       #从前向后开始计算,当字符串的长度超过size时,超过部分用替换符号替代,s21 = ********************** qwer12 345 @#$%^
s22 = s.ljust(40,'*')        #从后向前开始计算,当字符串的长度超过size时,超过部分用替换符号替代,s22 =  qwer12 345 @#$%^ **********************

s17 = s.endswith(' ')              #字符串以什么结尾,返回返回Ture或False
s18 = s.startswith(' ')            #字符串以什么开头,返回Ture或False

#将列表中字符通过给出的连接拼为字符串,列表中的值需要时字符串
li = ['q','w','e']
s20 = '*'.join(li)
print(s20)
('qw','4321')  #字符替换s23 =  4321er12 345 @#$%^

推荐阅读