Python - 文本字符串、二进制数据

文本字符串

1. Unicode

1.1 Unicode字符串

Python3的字符串是Unicode字符串不是字节数组。这是与python2相比最大的差别。

  • 用\u及4个十六进制的数字可以从Unicode256个基本多语言平面中指定一个特定某一特定字符。
  • 我们需要使用更多的比特位来存储那些位于更高平面的字符。Python为此而设计的转义序列以\U开头,后面紧跟8个十六机制的数字,其中最左一位需为0。
  • 也可以通过\N{name}来引用某一字符。
def unicode_test(value):
    import unicodedata
    name = unicodedata.name(value)  #name()接受一个Unicode字符,返回大写形式的名称;
    value2 = unicodedata.lookup(name)   #lookup()接受不区分大小写的标准名称,返回一个Unicode字符;
    print('value = "%s", name = "%s", value= "%s"' % (value, name, value2))

unicode_test('a')

#value = "a", name = "LATIN SMALL LETTER A", value= "a"

通过字符名称或者编码值来指定café这个词:

place = 'caf\u00e9'	
print(place)

#café

place = 'caf\N{LATIN SMALL LETTER E WITH ACUTE}'
print(place)

#café

字符串函数len可以计算字符串中Unicode字符的个数,而不是字节数:

print(len('$'))

#1

print(len('\U0001f47b'))

#1

1.2 使用UTF-8编码和解码

当需要与外界进行数据交互时需要完成两件事情:

  • 将字符串编码为字节
  • 将字节解码为字符串

UTF-8是Python、Linux、以及HTML的标准文本编码格式。如果创建Python字符串时使用了从别的文本源(例如网页)赋值粘贴过来的字符串。一定要确保文本源使用的是UTF-8编码。

1.3 编码

编码是将字符串转化为一系列字节的过程。字符串的encode()函数锁接收的第一个参数是编码方式名。可选的编码方式列表如下:

编码说明
‘ascii’经典的7比特ASCII编码
‘utf-8’最常用的以8比特为单位的变长编码
‘latin-1’也被称为ISO 8895-1编码
‘cp-1252’Windows常用编码
‘unicode-escape’Python中Unicode的转移文本格式,\uxxxx或\Uxxxxxxxx
snowmain = '\u2603'	#仅包含一个字符的Unicode字符串
print(len(snowmain))	
print(len(snowmain.encode('utf-8')))	#将Unicode字符编码为字节序列,utf-8是一种变长编码方式。所以占用3字节的空间。编码后的snowmain变成了bytes类型(字节型)。 bytes类型是指一堆字节的集合,在python中以b开头的字符串都是bytes类型。

#1
#3

encode()函数可以接受额外的第二个参数来帮助我们避免编码异常。它的默认值是’strict’。

snowmain = '\u2603'
print(snowmain.encode('ascii', 'ignore'))
print(snowmain.encode('ascii', 'replace'))
print(snowmain.encode('ascii'))

#b''
#b'?'
'''
Traceback (most recent call last):
  File "test.py", line 239, in <module>
    print(snowmain.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 0: ordinal not in range(128)
'''

1.4 解码

解码试讲字节序列转化为Unicode字符串的过程。我们从外界(文件,数据库,网站,网络API等)获得的所有文本都是经过编码的字节串。我们需要知道它是以何种方式编码的,这样才能逆转编码过程以获得Unicode字符串。

place = 'caf\u00e9'
print(place)
place_encode = place.encode('utf-8')
print(place_encode)
print(place_encode.decode('utf-8'))

#café
#b'caf\xc3\xa9'
#café

尽可能统一使用UTF-8编码。出错率低,兼容性好,可以表达所有的Unicode字符,编码解码速度快等优点。

2. 格式化

Python有两种格式化字符串的方式。

2.1 使用%的旧式格式化

旧式格式化形式为string % data。它仅由%以及一个用于指定数据类型的字幕组成。

%s字符串
%d十进制整数
%x十六进制整数
%o八进制整数
%f十进制浮点数
%e以科学计数法表示的浮点数
%g十进制或科学计数法表示的浮点数
%%文本值%本身

字符串和整数的插值操作:

action = 'hello'
num = 20
flow = 70.003
print('%s world' % action)
print('%d' % num)
print('%10d' % num)
print('%f' % flow)
print('%10f' % flow)

#hello world
#20
#        20
#70.003000
# 70.003000

2.2 使用{}和format的新式格式化

新式格式化最简单的用法如下:

a = 12
b = 7.03
c = 'hello'
print(f'{a} {b} {c}')	#格式化字面量	
print('{} {} {}'.format(a, b, c))	#format()方法
print('{b} {a} {c}'.format(a=11, b=7.01, c='world'))

#字典
d = {'a':1, 'b': 7.03, 'c':'world'}
print('{0[a]} {0[b]} {0[c]} {1}'.format(d, 'other'))
print('{0:d} {1:f} {2:s}'.format(a, b, c))
print('{a:d} {b:f} {c:s}'.format(a=41, b=7.01, c='else'))

#12 7.03 hello
#12 7.03 hello
#7.01 11 world
#1 7.03 world other
#12 7.030000 hello
#41 7.010000 else

3. 使用正则表达式匹配

3.1 模式匹配方法

import re 

result = re.match('you', 'you are my')  #第一个参数:匹配的模式(pattern);第二个参数:匹配的对象(source字符串)
print(result)

you = re.compile('you')
result = you.match('you are my')    #从源字符串的开头开始匹配
print(result)

if result:
    print(result.group())
    
are = re.search('are', 'you are my')
if are:
    print(are.group())

are = re.search('.are', 'you are my')	#返回第一次匹配成功
if are:
    print(are.group())
 
are = re.search('.*are', 'you are my')
if are:
    print(are.group())
    
are = re.match('.*are', 'you are my')
if are:
    print(are.group())
    
#<re.Match object; span=(0, 3), match='you'>
#<re.Match object; span=(0, 3), match='you'>
#you
#are
# are
#you are
#you are

除了以上方法,还有findall()、split()、sub()等方法。

  • 使用 . 代表任意除\n外的字符
  • 使用 * 表示任意多个字符。(包括0个)
  • 使用 ? 表示可选字符(0个或1个)

3.2 模式:特殊字符

模式匹配
\d一个数字字符
\D一个非数字字符
\w一个字母或数字字符
\W一个非字母或非数字字符
\s空白符
\S非空白符
\b单词边界
\B非单词边界
import string
import re

print(string.printable)
print(len(string.printable))
print(re.findall('\d', string.printable))


'''
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~



100
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
'''

3.3 模式:使用标识符

表中:expr和其他斜体单词表示合法的正则表达式。

模式匹配
abc文本值abc
(expr)expr
expr1|expr2expr1或expr2
.除\n外的任何字符
^源字符串的开头
$源字符串的结尾
prev?0个或1个prev
prev*0个或多个prev,尽可能的多匹配
prev*?0个或多个prev,尽可能的少匹配
prev+1个或多个prev,尽可能的多匹配
prev+?1个或多个prev,尽可能的少匹配
prev{m}m个连续的prev
prev{m, n}m个到n个连续的prev,尽可能的多匹配
prev{m, n}?m个到n个连续的prev,尽可能的少匹配
[abc]a或b或c(和a|b|c一样)
[^abc]非(a或b或c)
prev(?=next)如果后面为next,返回prev
prev(?!next)如果后面非next,返回prev
(?<=prev)next如果前面为next,返回prev
(?<!prev)next如果前面非next,返回prev
import string
import re

source = 'you are you are you are hello world'
print(re.findall('are', source))
print(re.findall('^are', source))
print(re.findall('^you are', source))
print(re.findall('hello$', source))
print(re.findall('hello world$', source))

print(re.findall('you|are', source))

#['are', 'are', 'are']
#[]
#['you are']
#[]
#['hello world']
#['you', 'are', 'you', 'are', 'you', 'are']

3.4 模式:定义匹配的输出

当使用match()或searc()时,所有的匹配会以m.group()的形式返回到对像m中。如果用括号将某一模式包裹起来,括号中模式匹配得到的结果归入自己的group中,而调用group()可以得到包含这些匹配的元组。

import string
import re

m = re.search(r'(. are\b).*(\bhello)', source)
print(m.group())
print(m.groups())

#u are you are you are hello
#('u are', 'hello')

二进制数据

1.1 字节和字节数组

  • 字节是不可变的,像字节数据组成的元组
  • 字节数组是可变的,想字节数据组成的列表
blist = [1, 2, 3, 255]
the_bytes = bytes(blist)
print(the_bytes)

the_array = bytearray(blist)
print(the_array)

#b'\x01\x02\x03\xff'
#bytearray(b'\x01\x02\x03\xff')

print(the_bytes[0])

#1

the_bytes[0] = 1	#不可改变

#TypeError: 'bytes' object does not support item assignment

1.2 大小端

标识符字节序
<小端方案
>大端方案

1.3 位运算符

运算符描述
&
|
^异或
~翻转
<<左位移
>>右位移
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值