Skip to content

字符串与中文编码

字符串常用方法

  • len() 计算字符串长度

在 python 中,数字、英文、小数点、下划线和空格各占一个字节;汉字在 GBK/GB2312 编码中占 2 个字节,在 UTF-8/Unicode 中一般占 3 个字节(或 4 个字节)

1
2
3
In [1]: str1 = "人生苦短,我用Python!"
In [2]: print(len(str1))
14

默认情况下,通过 len() 函数计算字符串的长度时,不区分英文、数字和汉字,所有字符都认为是一个

在实际开发中,有时需要获取字符串实际所占的字节数,可以通过 encode() 方法进行编码后再进行获取

1
2
3
4
In [3]: print(len(str1.encode()))
28
In [4]: print(len(str1.encode('gbk')))
21
  • str.split(sep, maxsplit) 分割字符串

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

  • count(): 检索指定字符串在另一个字符串中出现的次数
  • find(): 检索是否包含指定的子字符串
  • index()
  • rindex()
  • startswith()
  • endswith()

  • lower()

  • upper()

  • strip(): 去除字符串左右两侧的空格和特殊字符

  • lstrip()
  • rstrip()

格式化字符串f-string: https://blog.csdn.net/sunxb10/article/details/81036693

注意 f-string 的大括号里面不能有\

使用 format() 格式化字符串

1
str.format(args)

参数说明:str,用于指定字符串的显示样式(即模板)。在创建模板时,需要使用“{}”和":"指定占位符,基本语法格式如下:

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

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

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

args: 用于指定要转换的项,如果有多项,则用逗号进行分隔

1
2
3
4
5
6
7
In [7]: template = '编号: {:0>9s}  公司名称:  {:s}  官网: http://www.{:s}.com'

In [8]: template.format('7', '百度', 'baidu')
Out[8]: '编号: 000000007  公司名称:  百度  官网: http://www.baidu.com'

In [9]: template.format('8', '腾讯', 'qq')
Out[9]: '编号: 000000008  公司名称:  腾讯  官网: http://www.qq.com'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
In [10]: pi = 3.1415926

In [11]: "{:.2f}".format(pi)
Out[11]: '3.14'

In [17]: "{:.2f}".format(1.256)  # 四舍五入保留两位小数
Out[17]: '1.26'

In [20]: "{:.2f}".format(1.254)
Out[20]: '1.25'

In [23]: "{:.2f}".format(1.2554)
Out[23]: '1.26'

In [12]: "{:+.2f}".format(pi)
Out[12]: '+3.14'

In [13]: "{:.0f}".format(pi)
Out[13]: '3'

In [15]: "{:,}".format(100000000000)
Out[15]: '100,000,000,000'

In [16]: "{:.2%}".format(0.005)
Out[16]: '0.50%'

In [17]: "{:.2e}".format(233333)
Out[17]: '2.33e+05'

In [8]: "{:02d}".format(0)
Out[8]: '00'

In [9]: "{:06d}".format(905)
Out[9]: '000905'

不以科学记数法展示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
In [1]: 123.70 / 123.69
Out[1]: 1.000080847279489

In [2]: 123.70 / 123.69 - 1
Out[2]: 8.084727948909354e-05

In [3]: "{:f}".format(123.70 / 123.69 - 1)
Out[3]: '0.000081'


In [4]: "{:f}".format(123.70 / 123.76 - 1)
Out[4]: '-0.000485'

In [5]: 123.70 / 123.76 - 1
Out[5]: -0.0004848093083387184

字符编码

在 Python 中编写代码的时候,如果用到指定字符编码类型的中文编码,需要在文件开头加上中文声明注释,这样可以在程序中指定字符编码类型的中文编码,不至于出现代码错误

1
# -*- coding: UTF-8 -*-
1
#coding=utf-8

-*- 没有特殊作用,只是为了美观才加上的

ASCII编码:美国标准代码,将各种东西(英文字母,数字,标点,字符)换成计算机识别的二进制数,一共265个字符,不支持汉字

Unicode:全球所有字符的编码,但是没有规定的保存方式,65----》A  

GBK编码:汉字编码,进行了扩展,包含生僻字,存储编码

GB2312:汉字处理,比较少,存储编码

GB2312,GBK,GB18030,是兼容的,包含的字符个数:GB2312 < GBK < GB18030

UTF-8:表示把unicode编码存储的时候,把一个汉字或者其他字符,保存为3个字节

文本字符串和字节字符串的转换
str(文本)-----(encode)------bytes(字节)
bytes(字节)----(decode)-----str(文本)

编码(encode)过程是将Unicode形式转化为utf-8等其他形式
解码(decode)过程是将utf-8等其他形式转化为Unicode形式

Unicode形式的字符串的type是str,utf-8等其他形式的字符串的type是bytes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
In [33]: a = '中文'

In [34]: aa = a.encode('utf-8')

In [35]: aa
Out[35]: b'\xe4\xb8\xad\xe6\x96\x87'

In [36]: a.encode('gbk')
Out[36]: b'\xd6\xd0\xce\xc4'

In [37]: aa.decode('utf-8')
Out[37]: '中文'

In [38]: '\u4e2d\u6587'
Out[38]: '中文'

In [43]: print('\u4e2d\u6587')
中文

In [42]: '\u0041'
Out[42]: 'A'
  • '\u4e2d\u6587'就是中文二字对应的Unicode编码
  • b'\xe4\xb8\xad\xe6\x96\x87'就是中文二字对应的utf-8编码
  • b'\xd6\xd0\xce\xc4'就是中文二字对应的gbk编码
  • 0041 是 65 的十六进制形式,65 是 A 对应的字符编码
  • 其中\u和\x都是转义字符,和\n换行符类似
  • \x表示十六进制数,每个\x后面跟两位,每一位都是0-9abcdef这16个中的一个。两位共可以表示16*16=256个数,即可以表示2^8=256,8位的二进制数可以表示的数。也就是说一个\x可以代表一个字节
  • \u表示Unicode编码,一个\u后面接4位的16进制数,每一位也是0-9abcdef这16个中的一个,4位可以表示16位二进制数可以表示的数,所以说一个\u可以代表两个字节
  • 从字节的角度我们再来看一下这个输出,“中文”两个字
    • 在Unicode编码中占4个字节
    • 在utf-8编码中占6个字节
    • 在gbk编码中占4个字节 
  • 再注意到'\u4e2d\u6587'直接输出和print都会出现“中文”二字,进一步说明python3中我们通常说的字符其实就是Unicode,将他们看成完全一样的就好
  • 输出'\u4e2d\u6587'这种转义字符时,是识别了\u,自动通过对照表将后面的那串字节显示成了中文
  • 对于b''这种前面有个b的,type都变了,不是str而是bytes,这种在print时会原样输出

Unicode编码转换- 站长工具

忽略读取错误

我们要解码的数据不符合我们期望的类型,所以有时候我们知道数据的编码格式,但是其中有一些其他格式的数据,这样我们就要将其他的格式数据进行忽略,否则解码会报错,程序运行不下去,在 decode 中添加’ignore’参数即可

file = open(path, encoding=’gb18030’, errors=’ignore’)

建议

关于默认编码的建议是:别依赖默认值,始终在程序中显式的指定编码,会避免很多问题 

其他

如果需要文件为 UTF-8 without BOM 编码格式,需要在代码中设置encodingutf-8-sig