导语:本文章记录了本人在学习Python基础之数据结构篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流。

本章重点:

1、了解字符字节等概念,编解码问题;

2、熟悉字符的规范化处理和双模式API。

一、基本概念

Unicode

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

来自英文bit,音译为“比特”,表示二进制位。位是计算机内部数据储存的最小单位,11010100是一个8位二进制数。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以表示00、01、10、11四种(22)状态;三位二进制数可表示八种状态(23)。

字节

字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)。八位二进制数最小为00000000,最大为11111111;通常1个字节可以存入一个ASCII码,2个字节可以存放一个汉字国标码。

计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。一个字通常由一个或多个(一般是字节的整数位)字节构成。例如286微机的字由2个字节组成,它的字长为16;486微机的字由4个字节组成,它的字长为32位机。

字长

字长是指cpu的每个字所包含的位数。根据计算机的不同,字长有固定的和可变的两种。固定字长,即字长度不论什么情况都是固定不变的;可变字长,则在一定范围内,其长度是可变的。计算的字长是指它一次可处理的二进创数字的数目。计算机处理数据的速率,自然和它一次能加工的位数以及进行运算的快慢有关。如果一台计算机的字长是另一台计算机的两倍,即使两台计算机的速度相同,在相同的时间内,前者能做的工作是后者的两倍。

码位

又称字符的标识。在Unicode标准中以4~6个十六进制数字表示,并加前缀“U+”。例如字母A的码位是U+0041

编码

把码位转换成字节序列,调用s.encode()

解码

把字节序列转换成码位,调用s.decode()

编解码例子:

s="São Paulo"

a=s.encode('utf8')

print(a)#b'S\xc3\xa3o Paulo'

b=a.decode("utf8")

print(b)

output:São Paulo

二、编解码问题

1、编解码器

latin1( 即 iso8859_1)

一种重要的编码, 是其他编码的基础。 例如 cp1252 和Unicode( 注意, latin1 与 cp1252 的字节值是一样的, 甚至连码位也相同) 。

cp1252

Microsoft 制定的 latin1 超集, 添加了有用的符号, 例如弯引号和€( 欧元) ; 有些 Windows 应用把它称为“ANSI”, 但它并不是 ANSI 标准。

cp437

IBM PC 最初的字符集, 包含框图符号。 与后来出现的 latin1 不兼容。

gb2312

用于编码简体中文的陈旧标准; 这是亚洲语言中使用较广泛的多字节编码之一。

utf-8

目前 Web 中最常见的 8 位编码; 与 ASCII 兼容( 纯 ASCII 文本是有效的 UTF-8 文本) 。

utf-16le

UTF-16 的 16 位编码方案的一种形式; 所有 UTF-16 支持通过转义序列( 称为“代理对”, surrogate pair) 表示超过 U+FFFF 的码位。

2、了解编解码问题

了解有关Unicode错误的处理方法。

2.1 UnicodeEncodeError

编码出现的错误在于编码器可能无法对字符串编码,以中英文字符串为例:

city="DaLian大连"

print(city.encode("utf8"))#b'DaLian\xe5\xa4\xa7\xe8\xbf\x9e'

print(city.encode("iso8859_1"))

输出报错:

Traceback (most recent call last):

File "D:\韩文承\编程工作空间\Fluent Python\section4-1.py", line 10, in

print(city.encode("iso8859_1"))

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 6-7: ordinal not in range(256)

原因在于这个latin1不会对中午编码,所以我们需要处理这个EncodeError,处理如下:

print(city.encode("iso8859_1",errors="ignore"))#b'DaLian'

print(city.encode("iso8859_1",errors="replace"))#b'DaLian??'

print(city.encode("iso8859_1",errors="xmlcharrefreplace"))#b'DaLian大连'

errors="ignore"

跳过无法编码的字符,这样做通常不妥。

errors="replace"

用问号替代无法编码的字符,虽然损坏了数据,但用户收到了编码有问题的信号。

errors="xmlcharrefreplace"

用xml实体代替无法编码的字符。

2.2 UnicodeDecodeError

解码出现的错误在于陈旧的解码器能解码任何字节序列而不抛出错误,有时会解码出无用的、乱码的字符。以包含变音符号的字节序列为例:

c=b"Montr\xe9al"

print(c.decode("iso8859_1"))#Montréal

print(c.decode("cp1252"))#Montréal

print(c.decode("cp437"))#MontrΘal 输出已经有问题了

print(c.decode("koi8_r"))#MontrИal KOI8_R是编码俄文的,此处输出了俄文字母

print(c.decode("utf8"))

报错:

Traceback (most recent call last):

File "D:\韩文承\编程工作空间\Fluent Python\section4-1.py", line 19, in

print(c.decode("utf8"))

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 5: invalid continuation byte

原因在于utf_8检测到c不是有效utf_8字符串,抛出UnicodeDecodeError。处理如下:

print(c.decode("utf8",errors="replace"))#Montr�al。用�替代无法解码的字节

2.3 SyntaxError

如果加载的模块中包含utf_8之外的数据,那么解释器会报错SyntaxError。

3、Chardet

Chardet是Python的一个库,可以检测出未知字节序列的编码方式。

不要在二进制模式中打开文本文件。即使想判断编码,也该用Chardet!

4、BOM(byte-order mark)

字节序标记,这个标记针对非单字节非字符串外的其余数据(如short,int)指明字节存储的方式,具体分为大端存储和小端存储。

大端存储第一个字节是高位,容易判断数值的正负;

小端存储第一个字节是地位,容易进行数值的运算。

需要注意:TCP/IP协议规定网络字节序为大端字节序。这意味着主机字节序如果是小端存储必须转化为大端字节序才能通过网络发送数据。

To Learn More:https://zhuanlan.zhihu.com/p/...

三、文本处理

1、处理文本文件

编码默认值

在多系统处理文件时应显式制定编码,否则容易出现默认编码器无法解码字节序列的情况。

编辑器默认编码查询:locale.getpreferredencoding()#cp936

Unicode三明治原则

我们可以用一个简单的原则处理编码问题: 字节序列->字符串->字节序列。就是说程序中应当仅处理字符串,当需要保存到文件系统或者传输的时候,编码为字节序列。

2、规范化处理

Unicode字符串规范化

码位规范化函数:unicodedata.normalize(格式,字符串)

格式参数:

NFC:使用最少的码位构造等价字符串

NFD :使用基字符和组合字符构造等价字符串

NFKC 和NFKD:将兼容字符分解

对大多数应用来说NFC是最好的规范化形式。

from unicodedata import normalize

d="café"

e="cafe\u0301"

print(normalize("NFC",d)==normalize("NFC",e))#True

print(normalize("NFD",d)==normalize("NFD",e))#True

规范化之后两个不同的码位相等的。

保存文件之前最好用规范化函数unicodedata.normalize(“NFC”,字符串)清洗字符串

大小写折叠函数:str.casefold()

自Python3.4起,str.lower()和str.casefold()不同的结果有116个码位,占Unicode命名的总字符的0.11%

3、文本排序

Unicode 排序:unicode collation algorithm, UCA 使用 PyUCA 库。

下载地址:https://pypi.python.org/pypi/...

四、双模式API

双模式是指标准库中一些函数能够接受字符串或字节序列为参数,并根据类型进行处理。

API(Application Programming Interface)即应用程序接口。可以把 API 理解为一个软件组件或是一个 Web 服务与外界进行的交互的接口。通俗的理解是程序和程序之间的交互,交互就是传递数据,触发功能。

1、re模块:构建正则表达式处理字符串。

正则表达式:可以匹配文本片段的模式。

1.1语法介绍:

通配符:

.点dot:能够匹配任意的字符。

^尖号:从开始匹配,意味着开始的字符必须和partern一致方可匹配上,否则匹配返回none.。

$美元符号:从尾部开始匹配,尾部开始的字符必须和partern一致方可匹配上,否则匹配返回none.。

*星号:允许模式重复0次或多次。

+加号:允许模式重复1次或多次。

?问号:允许模式重复0次或1次。

{m,n}:允许模式重复m~n次。(贪婪匹配下直接匹配到n次)当m=n即为{m},只匹配m次。

用反斜线对特殊符号进行转义:

有时我们只想用特殊符号如dot“."的字面意思,而非作为通配符使用。例如匹配网站”baidu.com“中的点就需要转义,变成"baidu\.com",即只匹配”baidu.com“

字符集:

表示欲匹配字符的集合,相比较通配符中的点号而言范围更小一些。例如[0-9A-F]可以匹配一个十六进制的字符。

注意:一个字符集只能匹配一个字符,除非配合数量限定符使用!

预定义字符集

d,数字[0-9]

D,非数字[^\d]

s,空白字符,包括空格,trnfv

S,非空白字符[^\s]

w,单词字符[A-Za-z0-9_]

W,非单词字符[^\w]

选择符和子模式:

此项欲匹配的范围比字符集还要小。比如你只想匹配python和people这两个单词,就可以用管道符号(|),即“python|people"。

如果操作的不是整个模式partern而是模式的一部分,圆括号括起来的部分称作子模式,即“p(ython|eople)”

1.2重要的函数:

函数

描述

re.compile(pattern, flags=0)

根据正则表达式的字符串创建模式对象

re.search(pattern, string, flags=0)

在字符串中寻找模式

re.match(pattern, string, flags=0)

在字符串的开始处匹配模式

re.split(pattern, string, maxsplit=0, flags=0)

根据模式的匹配项来分割字符串

re.findall(pattern, string, flags=0)

列出字符串中模式的所有匹配项

re.finditer(pattern, string, flags=0)

返回一个迭代器,其中包含满足正则表达式要求的match objects

re.sub(pattern, repl, string, count=0, flags=0)

将字符串中所有pat的匹配项用repl替换

re.escape(pattern) 将字符串中所有特殊正则表达式字符转义

Tips:re.compile构建模式,对于重复式的匹配效率更高。

flags参数介绍:

re.I 或re.IGNORECASE

使匹配忽略字母大小写。

re.L或re.LOCALE

影响 “w, “W, “b, 和 “B,这取决于当前的本地化设置。

re.M或re.MULTILINE

使用本标志后,‘^’和‘$’匹配行首和行尾时,会增加换行符之前和之后的位置。

re.S或re.DOTALL

使点号这个特殊字符完全匹配任何字符,包括换行;没有这个标志, “.” 匹配除了换行符外的任何字符。

re.X或re.VERBOSE

当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠之后。它也可以允许你将注释写入 RE,这些注释会被引擎忽略;注释用 “#”号 来标识,不过该符号不能在字符串或反斜杠之后。

1.3MatchObject对象

MatchObject是一次成功匹配后返回的对象类型,它支持如下的重要方法:

group([group1, …]):

获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。

groups():

以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。

start([group]):

返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。

end([group]):

返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。

span([group]):

返回(start(group), end(group))。

1.4贪婪和非贪婪模式

*和+这类数量限定符默认是贪婪的,即尽可能多的匹配满足要求的字符串。只有在其后加上问号?方可变成非贪婪的。

贪婪与非贪婪eg:

import re

greedy=re.compile(r"<.>")#贪婪

non_greedy=re.compile(r"<.>")#非贪婪,利用问号限制

print(greedy.search("

Chapter 1 - 介绍正则表达式

"))

print(non_greedy.search("

Chapter 1 - 介绍正则表达式

"))

输出:

对字符串和字节序列进行re匹配:

import re

text_str = "Ramanujan saw \u0be7\u0bed\u0be8\u0bef as 1729 = 1³ + 12³ = 9³ + 10³."

text_byte=text_str.encode('utf_8')

str_number=re.compile(r"\d+")

str_word=re.compile(r"\w+")

byte_number=re.compile(rb"\d+")

byte_word=re.compile(rb"\w+")

print("str_number",str_number.findall(text_str))

print("str_word",str_word.findall(text_str))

print("byte_number",byte_number.findall(text_byte))

print("byte_word",byte_word.findall(text_byte))

输出:

str_number ['௧௭௨௯', '1729', '1', '12', '9', '10']

byte_number [b'1729', b'1', b'12', b'9', b'10']

str_word ['Ramanujan', 'saw', '௧௭௨௯', 'as', '1729', '1³', '12³', '9³', '10³']

byte_word [b'Ramanujan', b'saw', b'as', b'1729', b'1', b'12', b'9', b'10']

分析:通过分别对字符串和字节序列进行数字、单词字符的匹配操作,容易发现对字节序列的匹配仅限于ASCII中的数字和单词字符,而对字符串的匹配会包含更多的泰米尔数字和上标等其他字符。

To Learn More: https://docs.python.org/3/lib...

2、os模块:

os.listdir() :

用于返回指定的文件夹包含的文件或文件夹的名字的列表。这个列表以字母顺序。

os.fsencode(filename):

如果 filename 是 str 类型或bytes 类型,使用sys.getfilesystemencoding() 返回的编解码器把 filename 编码成字节序列; 否则, 返回未经修改的 filename 字节序列。

os.fsdecode(filename):

如果 filename 是 bytes 类型或 str 类型, 使用sys.getfilesystemencoding() 返回的编解码器把 filename 解码成字符串; 否则, 返回未经修改的 filename 字符串。

python序列符号_Python中的文本和字节序列相关推荐

  1. python 温度 符号_python中温度单位如何转换?

    温度有摄氏度和华氏度两个单位,我们通常使用的是摄氏度,对于转换成华氏度,很多小伙伴记不住公式.作为万能的计算机,它是可以帮助我们解决温度单位转换的问题.本文主要演示python中进行温度单位转换的代码 ...

  2. Python中文本和字节序列的处理

    文本和字节序列 字节问题 字节概要 基本的编解码器 编码问题 处理UnicodeEncodeError 处理UnicodeDecodeError 处理文本文件 字节问题 "字符串" ...

  3. 流畅的python学习笔记(三):数据结构(3:文本和字节序列)

    文本和字节序列 大纲 1. 字符问题 2. 字节概要 2.1 结构体和内存视图 3. 基本的编解码器 4. 了解编解码问题 4.1 处理UnicodeEncodeError 4.2 处理Unicode ...

  4. [流畅的Python][4][文本和字节序列]

    第4章 文本和字节序列 人类使用文本,计算机使用字节序列.--------Esther Nam和Travis Fischer Python3明确地区分了人类可读的文本字符串和原始的字节序列 4.1 字 ...

  5. 读书笔记:《流畅的Python》第4章 文本和字节序列

    # 第四章 文本和字节序列"""内容提要:1.Unicode字符串2.二进制序列3.在二者之间转换使用的编码4.字符/码位/字节表述5.bytes/bytearray/m ...

  6. 流畅的python读书笔记④:文本和字节序列

    人类使用文本,计算机使用字节序列. --Esther Nam 和 Travis Fischer "Character Encoding and Unicode in Python" ...

  7. 利用Python提取PDF文件中的文本信息

    如何利用Python提取PDF文件中的文本信息 日常工作中我们经常会用到pdf格式的文件,大多数情况下是浏览或者编辑pdf信息,但有时候需要提取pdf中的文本,如果是单个文件的话还可以通过复制粘贴来直 ...

  8. python并且符号_Python如何从文字中分离标点符号

    所以我想用空格将文本与标点符号分开.Python如何从文字中分离标点符号 my_text = "!where??and!!or$$then:)" 我想要有一个! where ?? ...

  9. python中集合是序列吗_Python中序列,列表,元组,字典及集合

    1.序列 一块用于存放多个值的连续内存空间,且按一定顺序排列,每个值都分派一个数字,称为索引或位置 (1).索引 序列中的每个元素都有一个编号,从0开始 若负数作为索引时,是从-1开始的,最后一个元素 ...

最新文章

  1. 喜讯不断,BCH又迎来两个代币发行方案
  2. python 结构体数组 定义_一篇文章弄懂Python中所有数组数据类型
  3. echart 圆饼图 显示单位_玩转ECharts之实现“1/2圆的玫瑰图”
  4. mysql通用查询日志_MySQL通用查询日志(GeneralQueryLog)_MySQL
  5. kfold_机器学习gridsearchcv(网格搜索)和kfold validation(k折验证)
  6. 44. xargs命令
  7. 如何更好的组织你的Laravel模型
  8. 为什么现在物质越来越丰富,人的幸福感反而越来越低?
  9. 教资支付显示找不到服务器,教师资格证报名支付的问题,点了支付总是找不到服..._教师资格考试_帮考网...
  10. 第3章第1讲算法与流程图
  11. MAC上VSCode无Git源代码管理的解决办法
  12. 爬虫练习(二)—股票信息抓取
  13. 多示例学习距离度量 (distance measures)和集合核 (set-kernel)
  14. mysql导入excel
  15. OSChina 周一乱弹 ——老东西!爷爷我!帮你拿!
  16. KOLO是如何赋能NFT音乐行业?
  17. 自律训练法 John Sehorz
  18. vue.js请求数据
  19. CSUST 2007 我爱吃烧烤 题解(状压dp)
  20. 墨云saas系统总结

热门文章

  1. Python代码这样写更优雅(转)
  2. unity 常用函数
  3. .net String.Format数字格式化输出
  4. 什么是一致性Hash算法?
  5. 噪声控制简史,以及几个简单的声学概念
  6. 计算机网络在实践中的应用,计算机网络技术及在实践中的应用
  7. 2个字符串相等 swift_Swift快速入门(一)之 Swift基础语法
  8. matplotlib 散点图_matplotlib画图 绘制散点图案例
  9. Vue3 组件通信学习笔记
  10. 十三、axios框架学习