python3操作数据
\u+4个十六进制的数字:获取Unicode256个基本多语言平面中指定某一特定字符 \U + 8个十六进制的数字:获取更多的比特位来存储那些位于更高平面的字符
\N{name}引用某一字符,name为该字符的标准名称
unicodedata模块的两个函数:lookup()--接受不区分大小写的标准名称,返回一个Unicode字符;那么()--接受一个Unicode字符,返回大写形式的名称
# _*_ coding: utf-8_*_
import unicodedata
def unicode_test(value):
name = unicodedata.name(value)
values = unicodedata.lookup(name)
print('value="%s", name="%s", values="%s"' % (value,name,values))
unicode_test('A')
unicode_test('$')
unicode_test('\u00a2')
unicode_test('\u2603') #当缺失对应字符的图片时,会以站位符的形式来显示(用dingbat字体)
unicode_test('\u00E9')
print(unicodedata.lookup('LATIN SMALL LETTER E WITH ACUTE'))
print('\u00e9')
print('\N{LATIN SMALL LETTER E WITH ACUTE}')
print(len('$'))
print(len('\U0001f47b')) #len()可以计算字符串中Unicode字符的个数,而不是字节数
D:\MyPython>python test2.py
value="A", name="LATIN CAPITAL LETTER A", values="A"
value="$", name="DOLLAR SIGN", values="$"
value="¢", name="CENT SIGN", values="¢"
value="?", name="SNOWMAN", values="?"
value="é", name="LATIN SMALL LETTER E WITH ACUTE", values="é"
é
é
é
1
1
使用UTF-8编码和解码
当与外界进行数据交互时则需要完成两件事:1.将字符串编码为字节;2.将字节解码为字符串
utf_8动态编码:为ascii字符分配1字节;为拉丁语系的语言分配2字节;为其他的位于基本多语言平面的字符分配3字节;为剩下的字符集分配4字节;
编码方式:
编码 说明
'ascii' 经典的7比特ascii编码
'utf-8' 最常用的以8比特为单位的变长编码
'latin-1' 也被称为ISO 8859-1编码
'cp-1252' Windowss常用编码
'unicode-escape' Python中Unicode的转义文本格式\uxxxx或者\Uxxxxxxxx
snowman = '\u2603'
print(len(snowman))
ds = snowman.encode('utf-8')
print(len(ds))
print(ds)
D:\MyPython>python test2.py
1
3
b'\xe2\x98\x83'
不以相同的方式进行编码会出错,encode()函数可以接受额外的第二个参数来避免错误,默认值是'strict'
# _*_ coding: utf-8_*_
snowman = '\u2603'
print(snowman.encode('ascii','ignore')) #抛弃无法编码的字符
print(snowman.encode('ascii','replace')) #将无法编码的字符替换成?
print(snowman.encode('ascii','backslashreplace')) #Unicode转义符序列的可打印版
print(snowman.encode('ascii','xmlcharrefreplace')) #用于创建网页中使用的字符实体串
D:\MyPython>python test2.py
b''
b'?'
b'\\u2603'
b'☃'
解码
# _*_ coding: utf-8_*_
snowman = '\u2603'
print(snowman)
snowman = snowman.encode('utf-8')
print(snowman.decode('utf-8'))
print(snowman.decode('ascii'))
print(snowman.decode('latin-1'))
D:\MyPython>python test2.py
?
?
Traceback (most recent call last):
File "test2.py", line 6, in <module>
print(snowman.decode('ascii'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)
格式化
%d 十进制整数
%x 十六进制整数
%o 八进制整数
%f 十进制浮点数
%e 以科学计数法表示的浮点数
%g 十进制或科学计数法表示的浮点数
%% 文本值%本身
# _*_ coding: utf-8_*_
print('%s' % 42)
print('%o' % 42)
print('%f' % 42.03)
print('%e' % 42.03)
print('%g' % 42.03)
print('%g' % 42.033333333333)
n = 42
f = 7.03
s = 'string cheese'
print('%d %f %s' % (n,f,s)) #默认宽度格式化
print('%10d %10f %10s' % (n,f,s)) #为每个设置最小域宽为10个字符,右对齐,左侧不够用空格填充
print('%-10d %-10f %-10s' % (n,f,s)) #为每个设置最小域宽为10个字符,左对齐,右侧不够用空格填充
print('%10.4d %10.4f %10.4s' % (n,f,s)) #浮点数的精度限制在小数点后4位
print('%*.*d %*.*f %*.*s' % (10,4,n,10,4,f,10,4,s)) #为每个设置最小域宽为10个字符,右对齐,左侧不够用空格填充
D:\MyPython>python test2.py
42
52
42.030000
4.203000e+01
42.03
42.0333
42 7.030000 string cheese
42 7.030000 string cheese
42 7.030000 string cheese
0042 7.0300 stri
0042 7.0300 stri
使用{}和format的新格式化
# _*_ coding: utf-8_*_
n = 42
f = 7.03
s = 'string cheese'
print('{} {} {}'.format(n,f,s))
print('{2} {0} {1}'.format(f,s,n)) #指定插入的顺序
print('{n} {f} {s}'.format(n=42,f=7.03,s='string cheese'))
d = {'n':42, 'f':7.03, 's':'string cheese'}
print('{0[n]} {0[f]} {0[s]} {1}'.format(d,'other')) #{0}代表整个字典,{1}代表后面的字符串’other‘
print('{0:d} {1:f} {2:s}'.format(n,f,s))
print('{n:d} {f:f} {s:s}'.format(n=42,f=7.03,s='string cheese'))
print('{0:10d} {1:10f} {2:10s}'.format(n,f,s))
print('{0:>10d} {1:>10f} {2:>10s}'.format(n,f,s)) #右对齐
print('{0:<10d} {1:<10f} {2:<10s}'.format(n,f,s)) #左对齐
print('{0:^10d} {1:^10f} {2:^10s}'.format(n,f,s)) #居中对齐
print('{0:>10d} {1:>10.4f} {2:>10.4s}'.format(n,f,s)) #右对齐, 无法对整数设置精度
print('{0:!^20s}'.format('Big sale')) #填充字符,把它放在 :之后
D:\MyPython>python test2.py
42 7.03 string cheese
42 7.03 string cheese
42 7.03 string cheese
42 7.03 string cheese other
42 7.030000 string cheese
42 7.030000 string cheese
42 7.030000 string cheese
42 7.030000 string cheese
42 7.030000 string cheese
42 7.030000 string cheese
42 7.0300 stri
!!!!!!Big sale!!!!!!
使用正则表达式匹配
# _*_ coding: utf-8_*_
import re
source = 'Young Frankenstein'
m =re.match('You', source)
if m:
print(m.group()) #输出匹配到的对象
m = re.match('Frank', source) #match()只能检测以模式串作为开头的源字符串,但search()可以检测任何位置的匹配
if m:
print(m.group()) #没有输出
m = re.search('Frank', source)
if m:
print(m.group())
m = re.match('.*Frank', source) #.代表任何单一字符,*代表一个它之前的字符, .*代表任何多个字符(包括0个)
if m:
print(m.group())
m = re.findall('n', source)
print(m,'Found',len(m),'matches')
m = re.split('n', source)
print(m)
m = re.sub('n','?',source)
print(m)
D:\MyPython>python test2.py
You
Frank
Young Frank
['n', 'n', 'n', 'n'] Found 4 matches
['You', 'g Fra', 'ke', 'stei', '']
You?g Fra?ke?stei?
# _*_ coding: utf-8_*_
import string
import re
printable =string.printable
print(len(printable))
print(printable[0:50])
print(printable[50:])
print(re.findall('\d', printable)) #数字
print(re.findall('\w', printable)) #数字,字母,下划线
print(re.findall('\s', printable)) #空格符
x = 'abc' + '-/*' + '\u00ea' + '\u0115'
print(re.findall('\w', x)) #\d不仅仅适用于ascii字符,还可以匹配Unicode的数字字符
D:\MyPython>python test2.py
100
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN
OPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_']
[' ', '\t', '\n', '\r', '\x0b', '\x0c']
['a', 'b', 'c', 'ê', '?']
模式标识符
abc 文本值abc
(expr) expr
expr1|expr2 expr1或者expr2
. 除\n外的任何字符
^ 开头
$ 结尾
prev? 0或者1
prev* 0或多,尽可能多匹配
prev*? 0或多,尽可能少匹配
prev+ 1或多,尽可能多匹配
prev+? 1或多,尽可能少匹配
prev{m} m个连续
prev{m,n} m到n个连续,尽可能多匹配
prev{m,n}? m到n个连续,尽可能少匹配
[abc] a或b或c
[^abc] 非(a或b或c)
prev(?=next) 如果后面为next,返回prev
prev(?!next) 如果后面非next,返回prev
(?<=prev)next 如果前面为prev,返回next
(?<!prev)next 如果前面非prev,返回next
# _*_ coding: utf-8_*_
import string
import re
source = 'I wish I may,I wish I might have a dish of fish'
print(re.findall('\bfish', source)) #匹配任何以fish开头的单词,但匹配失败
#\b在字符串中表示退格,但在正则表达式中表示一个单词的开头位置,上面产生与
#转义符产生冲突,在模式串前添加r,起到表明为正则表达式,从而禁用字符串转义符
print(re.findall(r'\bfish', source))
D:\MyPython>python test2.py
[]
['fish']
模式:定义匹配的输出
import string
import re
source = 'I wish I may,I wish I might have a dish of fish'
m = re.search(r'(. dish\b).*(\bfish)', source)
print(m.group())
print(m.groups())
m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)
print(m.group())
print(m.groups())
print(m.group('DISH'))
print(m.group('FISH'))
D:\MyPython>python test2.py
a dish of fish
('a dish', 'fish')
a dish of fish
('a dish', 'fish')
a dish
fish
# _*_ coding: utf-8_*_
blist = [1,2,3,255]
the_bytes = bytes(blist)
print(the_bytes)
the_byte_array = bytearray(blist)
print(the_byte_array)
the_byte_array[1] = 127 #bytearray类可变性
print(the_byte_array)
the_bytes[1] = 127 #bytes类不可变性
D:\MyPython>python test2.py
b'\x01\x02\x03\xff'
bytearray(b'\x01\x02\x03\xff')
bytearray(b'\x01\x7f\x03\xff')
Traceback (most recent call last):
File "test2.py", line 10, in <module>
the_bytes[1] = 127
TypeError: 'bytes' object does not support item assignment
打印bytes或bytearray数据时,python会以\xxx的形式表示不可打印的字符,以asscii字符的形式表示可打印的字符
使用struct转换二进制数据
什么是大端法和小端法?
在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中的最小地址。
例如,假设一个类型为int的变量x的地址为0x100,即&x的值为0x100。那么x的4个字节将被存储在
存储器的0x100,0x101,0x102和0x103的位置。
字节序即为多字节对象存储在内存中的字节顺序,有两种不同的存储方案:大端法和小端法。现代的处理器大多为双端法,大小端都支持,可以配置称大端法或者小端法。
大端法
最高有效字节在最前面的方式称为大端法,例如假设变量x类型为int型,位于地址0x100的地方,其16进制值为0x12345678,地址范围为0x100到0x103字节。
对于大端法的机器来说:
0x100 | 0x101 | 0x102 | 0x103 |
---|---|---|---|
12 | 34 | 56 | 78 |
由上图可见,地址从左向右增长,x的最高有效字节12在最前面存储。这正好和我们平时书写习惯一致,先书写最高有效字节,再依次写其余字节。
小端法
最低有效字节在最前面的方式成为小端法,这正好和大端法相反,仍然用大端法中举的例子说明:
0x100 | 0x101 | 0x102 | 0x103 |
---|---|---|---|
78 | 56 | 34 | 12 |
由上图可见,地址依然从左向右增长,x的最低有效字节在最前面存储,与大端法相反。
x 跳过一个字节 1
b 有符号字节 1
B 无符号字节 1
h 有符号短整数 2
H 无符号短整数 2
i 有符号整数 4
I 无符号整数 4
l 有符号长整数 4
L 无符号长整数 4
Q 无符号long long型整数 8
f 单精度浮点数 4
d 双精度浮点数 8
p 数量和字符 1+数量
s 字符 数量
标识符紧跟字节序标识符的后面,5B代表BBBBB
# _*_ coding: utf-8_*_
import struct
valid_png_header = b'\x89PNG\r\n\x1a\n'
data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x9a\x00\x00\x00\x8d\x08\x02\x00\x00\x00\xc0'
if data[:8] == valid_png_header:
width,height = struct.unpack('>LL', data[16:24])
print('Valid PNG,width', width, 'height', height)
else:
print('Not a valid PNG')
print('0x9a:', 0x9a)
print('0x8d:', 0x8d)
print(struct.pack('>L', 154))
print(struct.pack('>L', 141))
print(struct.unpack('>2L', data[16:24]))
print(struct.unpack('>16x2L6x', data))
D:\MyPython>python test2.py
Valid PNG,width 154 height 141
0x9a: 154
0x8d: 141
b'\x00\x00\x00\x9a'
b'\x00\x00\x00\x8d'
(154, 141)
(154, 141)
其他二进制数据工具
# _*_ coding: utf-8_*_
from construct import Struct, Magic, UBInt32, Const, String
fmt = Struct('png', Magic(b'\x89PNG\r\n\x1a\n'),UBInt32('length'),Const(String('type',4),b'IHDR'),UBInt32('width'),UBInt32('height'))
data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x9a\x00\x00\x00\x8d\x08\x02\x00\x00\x00\xc0'
result = fmt.parse(data)
print(result)
print(result.width, result.height)
结果:
Container:
length = 13
type = b'IHDR'
width = 154
height = 141
154,141
使binascii()转换字节/字符串
import binascii
valid_png_header = b'\x89PNG\r\n\x1a\n'
print(binascii.hexlify(valid_png_header)) #将八进制打印成十六进制
print(binascii.unhexlify(b'89504e470d0a1a0a'))
D:\MyPython>python test2.py
b'89504e470d0a1a0a'
b'\x89PNG\r\n\x1a\n'
位运算符
整数a(十进制5,二进制0b0101)和整数b(十进制1,二进制0b0001)
本文是我在学习了丁嘉瑞的《Python语言及其应用》所做的笔记,只用于学习。