目前对于程序员来说,Unicode是一个非常重要的知识点.对于Python3.X以上的版本,字符串就是Unicode(用str函数来操作),但是对于Python2.7X以上的版本,str函数处理的是ASCII字符.(ASCII只是Unicode的一个子集),以下是不同版本的Python对字符串的处理:
1. 在Python3.X中有三种字符串类型:str用于Unicode(包含ASCII),bytes用于二进制数据(包含编码的文本),bytearray是可改变的bytes类型.
文件有两种模型:str实现Unicode编码,而二进制处理bytes类型,而不涉及任何的转换.
2. 在Python2.X中,"unicode"字符串代表Unicode文本,str处理八位文本和二进制数据,bytearray在2.6中有效而且在3.X中成为一部分.
文件中str用来处理简单的字符串文本,而codecs模块支持Unicode文本,用于其编解码.
对于Python来说,字符串实际上就是不可改变的字符序列,这也意味着它可迭代.
S = ' ' |
空字符串 |
S = "spam's" |
单双引号作用一样 |
S = 's\np\ta\x00m' |
转义符序列 |
S = """...multiline""" |
三引号区域字符串 |
S = r''\temp\spam |
原始字符串(转移字符不进行转移) |
S = b'sp\xc4m' |
byte字符串 |
S = u'sp\uooc4m' |
Unicode字符串 |
S1 + S2 |
字符串连接 |
S * 3 |
字符串重复 |
S[i] |
字符串索引 |
S[i:j] |
字符串分割 |
len(S) |
字符串长度 |
"a %s parrot" % kind |
字符串格式化表示 |
"a {0} parrot".format(kind) |
字符串格式化表示的方法 |
S.find('pa') |
字符串查询 |
S.rstrip() |
去除空白符 |
S.replace('pa', 'xx') |
字符串替换 |
S.split(',') |
字符串分割 |
S.isdigit() |
判断是否为十进制 |
S.lower() |
转换为小写 |
S.endswith('spa,') |
尾部字符串测试 |
'spam'.join(strlist) |
将列表以'spam'作为分隔符转换为字符串 |
S.encode('latin-1') |
Unicode编码 |
B.decode('utf8') |
Unicode解码 |
for x in S: print(x) |
可迭代 |
'spam' in s |
判断'spam'是否在S中 |
[c * 2 for c in S] |
列表推导式 |
map(ord, S) |
map函数 |
re.match('sp(.*)am', line) |
正则表达式对字符串的运用 |
对于Python来说,单双字符串是一样的.但是单引号字符串可内嵌于双引号字符串中(双引号字符串也可内嵌于单引号字符串中):
>>> 'shrubbery', "shrubbery" ('shrubbery', 'shrubbery') >>> 'knight"s', "knight's" ('knight"s', "knight's")备注:
1. 一般都是单引号在双引号字符串中,而很少有双引号字符在单引号字符串中.
2. 这里逗号是重要的,它起到元组的作用.如果去掉逗号,则字符串会自动拼接:
>>> title = "Meaning " 'of' " Life" >>> title 'Meaning of Life'
以分隔符"\"开始的为转移字符(后跟有意义的转移字符,而非无效的字符,如\n代表换行,而\p则代表字符串"\p").对于转移字符,实际上存储一个二进制的值:
>>> s = 'a\nb\tc' >>> s 'a\nb\tc' >>> print(s) a b c >>> len(s) 5
所有的转义格式如下:
\\,\',\",\a,\b,\f,\n,\r,\t,\v |
基本转义字符 |
\xhh |
十六进制值 |
\ooo |
八进制值 |
\0 |
Null:二进制0字符(并不代表字符串的结束,和C语言不一样) |
\N{ id } |
Unicode数据库ID |
\uhhhh |
Unicode字符(16位十六进制值) |
\Uhhhhhhhh |
Unicode字符(32位十六进制值) |
\other |
非转义字符 |
>>> s = 'a\0b\0c' >>> s 'a\x00b\x00c' >>> len(s) 5 >>> s = '\001\002\003' >>> s '\x01\x02\x03' >>> len(s) 3但是对于字符串来说,如果"\"后跟无效的转移字符,则"\"就直接被表示为一个字符"\":
>>> x = "C:\py\code" >>> x 'C:\\py\\code' >>> len(x) 10
但是如果我们不想被转移字符所困恼怎么办?我们可以在字符前面加字母"r":
>>> print("C:\new\test.dat") C: ew est.dat >>> print(r"C:\new\test.dat") C:\new\test.dat >>> path = r"C:\new\test.dat" >>> path 'C:\\new\\test.dat' >>> len(path) 15但是对于r来说,"\"却不能出现在末尾:
>>> r"...\" SyntaxError: EOL while scanning string literal
三引号字符串通常称为"区域字符串":即字符串可存在于多行之中.
不要在三引号字符串中添加注释,这样注释将会成为字符串的一部分.
而三引号字符串通常用于"文档字符串",用于说明一个函数或者一个类的作用.
我们可以使用"+"来连接字符串(因为字符串不可改变,所以我们实际上是新建一个字符串对象),使用"*"来重复字符串.
>>> len('abc') 3 >>> 'abc' + 'def' 'abcdef' >>> 'Ni!' * 4 'Ni!Ni!Ni!Ni!'但是Python和JavaScript(因为Python和JavaScript具有可比性)有一点不同之处在于:Python并不会自动进行类型的转换:
>>> 'abc' + 9 Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> 'abc' + 9 TypeError: cannot concatenate 'str' and 'int' objects而在JavaScript中,这是合法的.数字9会自动被转换成字符串'9'.
我们可以对字符串进行迭代操作,并且可以通过操作符"in"来判断是否在字符串中:
>>> myjob = "hacker" >>> for c in myjob: print(c, end = ' ') h a c k e r >>> "k" in myjob True >>> "z" in myjob False >>> 'spam' in 'abcspamdef' True
字符串是字符组成的一个不可改变的序列集合,所以我们可以对它进行索引和切片的操作.但是和C语言不一样的一处在于:Python允许负数索引,-1代表最后一个字符,-2代表倒数第二个,依次类推:
>>> S = 'spam' >>> S[0], S[-2] ('s', 'a') >>> S[1:3],S[1:],S[:-1] ('pa', 'pam', 'spa')我们可以给切片增加一个参数:步长(S[i:j:k],k表示一个步长)
>>> S = 'abcdefghijklmnop' >>> S[1:10:2] 'bdfhj' >>> S[::2] 'acegikmo'但是步长也可以是负数,代表递减:
>>> S = 'hello' >>> S[::-1] #这里等价于S[最尾部索引:0:-1] 'olleh' >>> S = 'abcdefg' >>> S[1:5:-1] '' >>> S[5:1:-1] 'fedc'而我们也可以使用slice函数来表示切片:
>>> 'spam'[1:3] 'pa' >>> 'spam'[slice(1, 3)] 'pa' >>> 'spam'[::-1] 'maps' >>> 'spam'[slice(None, None, -1)] 'maps'
Python会阻止任何产生歧义的转换,因为"+"在Python中既可以作为数值操作的加号,也可以作为字符串的连接,所以以下的操作存在错误:
>>> "42" + 1 Traceback (most recent call last): File "<pyshell#22>", line 1, in <module> "42" + 1 TypeError: Can't convert 'int' object to str implicitly一般情况下,我们只需要进行强制类型转换即可:
>>> int("42") + 1 43 >>> "42" + str(1) '421'还有其他额外的转换方式如:
ord:将相对应的字符转换为其整型表示
chr:将整型转换为相对应的字符表示
>>> ord('s') 115 >>> chr(115) 's' >>> S = '5' >>> S = chr(ord(S) + 1) >>> S '6' >>> int('5') 5 >>> ord('5') - ord('0') 5我们也可以使用int来指定基数,使用bin来显示二进制数:
>>> int('1101', 2) 13 >>> bin(13) '0b1101'
因为字符串是不可更改的字符序列,所以我们只能新建一个字符串,然后存储所更改的字符串的结果:
>>> S = 'splot' >>> id(S) 60510024 >>> S = S.replace('pl', 'pamal') >>> S 'spamalot' >>> id(S) 60483760通过格式化字符串来新建字符串也是不错的选择:
>>> 'That is %d %s bird!' % (1, 'dead') 'That is 1 dead bird!' >>> 'That is {0} {1} bird!'.format(1, 'dead') 'That is 1 dead bird!'
以下截图为字符串的所有方法,具体实现直接参考手册即可:
我们可以使用replace方法来修改字符串(在JavaScript中replace可以直接带正则表达式,但是Python中不行,Python应该import re模块,然后进行字符串的操作).而我们可以给replace传递第三个参数,告诉字符串修改几个子字符串:
>>> 'aa$bb$cc$dd'.replace('$', '--') 'aa--bb--cc--dd' >>> 'aa$bb$cc$dd'.replace('$', '--', 1) 'aa--bb$cc$dd' >>> 'aa$bb$cc$dd'.replace('$', '--', 2) 'aa--bb--cc$dd'备注:一般复杂的字符串操作,推荐使用正则表达式.
而如果要对字符串进行额外的一些操作,建议使用list函数将字符串转换为list,再铜鼓join将list转换为string:
>>> S = 'spammy' >>> L = list(S) >>> L ['s', 'p', 'a', 'm', 'm', 'y'] >>> L[3], L[4] = 'x', 'x' >>> L ['s', 'p', 'a', 'x', 'x', 'y'] >>> S = ''.join(L) >>> S 'spaxxy'
我们可以通过split来分割字符串:
>>> 'aaa,bbb,ccc'.split(',') ['aaa', 'bbb', 'ccc']
>>> line = 'The knights who say Ni!\n' >>> line.rstrip() 'The knights who say Ni!' >>> line.upper() 'THE KNIGHTS WHO SAY NI!\n' >>> line.isalpha() False >>> line.endswith('Ni!\n') True >>> line.startswith('The') True >>> line.find('Ni') 20 >>> 'Ni' in line True
字符串格式化有两种方式:'...%s...' % (values)和'...{}...'.format(values):
>>> 'That is %d %s bird' % (1, 'dead') 'That is 1 dead bird' >>> 'That is {0} {1} bird'.format("1", "dead") 'That is 1 dead bird' >>> 'That is {0} {1} bird'.format(1, "dead") 'That is 1 dead bird'格式化的基本语法如下:
Code |
Meaning |
s |
字符串 |
r |
类似s,但是以repr显示 |
c |
字符(整型或单个字符) |
d |
十进制整数 |
i |
整型 |
u |
有符号整数 |
o |
八进制 |
x |
十六进制 |
X |
十六进制,但是大写 |
e |
小写的浮点数,使用e表示 |
E |
大写的浮点数,使用e表示 |
f |
浮点数 |
F |
大写的浮点数 |
g |
浮点数:基于e或者f |
G |
浮点数:基于E或者F |
% |
等价于%% |
flags:设定一些标志,如"-"为指定宽度情况下向左靠拢,"0"则代表用0填充
>>> x = 1234 >>> res = 'integers:...%d...%-6d...%06d' % (x, x, x) >>> res 'integers:...1234...1234 ...001234'而%e,%f和%g用于显示不同的浮点数,我们甚至可以为它指定宽度和小数位个数:
>>> x = 1.23456789 >>> '%e | %f | %g' % (x, x, x) '1.234568e+00 | 1.234568 | 1.23457' >>> '%-6.2f | %05.2f | %+06.1f' % (x, x, x) '1.23 | 01.23 | +001.2' >>> '%s' % x, str(x) ('1.23456789', '1.23456789')我们能可以把精度当作一个参数来进行设置:当设置为*的时候
>>> '%f, %.2f, %.*f' % (1 / 3.0, 1 / 3.0, 4, 1 / 3.0) '0.333333, 0.33, 0.3333'
我们可以通过字典的键作为索引,来达到字符串格式化的目的:
>>> '%(qty)d more %(food)s' % {'qty' : 1, 'food' : 'spam'} '1 more spam'实际上这也不难理解:你设定的任何变量都是以字典的方式关联起来的:
>>> food = 'spam' >>> qty = 10 >>> vars() {'__builtins__': <module 'builtins' (built-in)>, 'res': 'integers:...1234...1234 ...001234', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None, '__spec__': None, '__name__': '__main__', 'qty': 10, 'food': 'spam', 'x': 1.23456789, '__package__': None}所以,我们只要提供一个对应的字典即可:
>>> '%(qty)d more %(food)s' % vars() '10 more spam'