返回顶部
首页 > 资讯 > 后端开发 > Python >Python中的文本和字节序列
  • 806
分享到

Python中的文本和字节序列

序列字节Python 2023-01-31 07:01:56 806人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

导语:本文章记录了本人在学习Python基础之数据结构篇的重点知识及个人心得,打算入门python的朋友们可以来一起学习并交流。 本章重点: 1、了解字符字节等概念,编解码问题;2、熟悉字符的规范化处理和双模式api。 一、基本概念 U

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

本章重点

1、了解字符字节等概念,编解码问题;
2、熟悉字符的规范化处理和双模式api

一、基本概念

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

  2. 来自英文bit,音译为“比特”,表示二进制位。位是计算机内部数据储存的最小单位,11010100是一个8位二进制数。一个二进制位只可以表示0和1两种状态(21);两个二进制位可以表示00、01、10、11四种(22)状态;三位二进制数可表示八种状态(23)。
  3. 字节
    字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit)。八位二进制数最小为00000000,最大为11111111;通常1个字节可以存入一个ASCII码,2个字节可以存放一个汉字国标码。

  4. 计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(Word)。一个字通常由一个或多个(一般是字节的整数位)字节构成。例如286微机的字由2个字节组成,它的字长为16;486微机的字由4个字节组成,它的字长为32位机。
  5. 字长
    字长是指cpu的每个字所包含的位数。根据计算机的不同,字长有固定的和可变的两种。固定字长,即字长度不论什么情况都是固定不变的;可变字长,则在一定范围内,其长度是可变的。计算的字长是指它一次可处理的二进创数字的数目。计算机处理数据的速率,自然和它一次能加工的位数以及进行运算的快慢有关。如果一台计算机的字长是另一台计算机的两倍,即使两台计算机的速度相同,在相同的时间内,前者能做的工作是后者的两倍。
  6. 码位
    又称字符的标识。在Unicode标准中以4~6个十六进制数字表示,并加前缀“U+”。例如字母A的码位是U+0041
  7. 编码
    把码位转换成字节序列,调用s.encode()
  8. 解码
    把字节序列转换成码位,调用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 <module>
    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&#22823;&#36830;'
  • errors="ignore"
    跳过无法编码的字符,这样做通常不妥。
  • errors="replace"
    用问号替代无法编码的字符,虽然损坏了数据,但用户收到了编码有问题的信号。
  • errors="xmlcharrefreplace"
    用xml实体代替无法编码的字符。

想了解更多错误处理方式可查阅Python官方Library:
https://docs.python.org/3/lib...

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 <module>
    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("<H1>Chapter 1 - 介绍正则表达式</H1>"))
print(non_greedy.search("<H1>Chapter 1 - 介绍正则表达式</H1>"))

输出:

<_sre.SRE_Match object; span=(0, 28), match='<H1>Chapter 1 - 介绍正则表达式</H1>'>
<_sre.SRE_Match object; span=(0, 4), match='<H1>'>

对字符串和字节序列进行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 字符串。

--结束END--

本文标题: Python中的文本和字节序列

本文链接: https://lsjlt.com/news/192185.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python中的文本和字节序列
    导语:本文章记录了本人在学习Python基础之数据结构篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流。 本章重点: 1、了解字符字节等概念,编解码问题;2、熟悉字符的规范化处理和双模式API。 一、基本概念 U...
    99+
    2023-01-31
    序列 字节 Python
  • 了解 Go 语言中的字节顺序和序列化机制
    从现在开始,我们要努力学习啦!今天我给大家带来《了解 Go 语言中的字节顺序和序列化机制》,感兴趣的朋友请继续看下去吧!下文中的内容我们主要会涉及到等等知识点,如果在阅读本文过程中有遇到不清楚的地方...
    99+
    2024-04-04
  • 使用awk怎么输出文本中的字段和列
    这期内容当中小编将会给大家带来有关使用awk怎么输出文本中的字段和列,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。例 1:我创建了一个名为 tecmintinfo.txt 的文本文件。# vi tecmi...
    99+
    2023-06-12
  • python列表和字符串的逆序遍历
    今天就跟大家聊聊有关python列表和字符串的逆序遍历,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。列表的逆序遍历a = [1,3,6,8,9]print(&qu...
    99+
    2023-06-15
  • Python统计序列和文件中元素的频度
    目录1、如何统计序列中元素的出现频度2、代码演示1、如何统计序列中元素的出现频度 实际案例: (1)某随机序列[12, 5, 6, 4, 6, 5, 5, 7, ...] 中找到出现...
    99+
    2024-04-02
  • 学习Go语言文档中的crypto/rand.Read函数生成随机字节序列
    学习Go语言文档中的crypto/rand.Read函数生成随机字节序列,需要具体代码示例随机数在计算机科学中起到非常关键的作用,例如密码学、安全性、加密算法等领域都需要随机数的支持。为了满足这种需求,Go语言提供了crypto/rand包...
    99+
    2023-11-04
    Go语言 关键词: crypto/randRead 随机字节序列
  • python如何查找序列中的数字
    你可以使用循环来遍历序列,并通过条件语句来判断是否是数字。以下是一个示例代码: sequence = [1, 'a...
    99+
    2024-04-08
    python
  • 如何使用Python中的序列化和反序列化
    如何使用Python中的序列化和反序列化,需要具体代码示例序列化和反序列化是在数据存储和传输过程中非常重要的概念。在Python中,我们可以使用pickle模块来实现序列化和反序列化操作。本文将详细介绍如何使用Python中的pickle模...
    99+
    2023-10-22
    Python 序列化 反序列化
  • Python编程中字符串和列表的基本知识讲解
    Python 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号来创建字符串。 创建字符串很简单,只要为变量分配一个值即可。例如: var1 = 'Hello World!' var...
    99+
    2022-06-04
    基本知识 字符串 列表
  • python有序序列和无序序列的含义是什么
    在Python中,有序序列和无序序列是指数据类型中的两种不同的集合类型。 有序序列(Ordered Sequence)指的是元素按照...
    99+
    2023-10-24
    python
  • Python中优化列表和字典
    Python中优化列表和字典,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在循环内代码:@timeit def append_inside_loop(lim...
    99+
    2023-06-16
  • Java版本和C++版本的二叉树序列化与反序列化
    目录1、什么是二叉树的序列化与反序列化2、先序方式序列化和反序列化3、后序方式序列化和反序列化4、层序方式序列化和反序列化5、完整代码 C++ 版1、什么是二叉树的序列化与反序列化 ...
    99+
    2024-04-02
  • Python中的字符串转义序列是什么
    Python中的字符串转义序列是一种特殊的字符序列,用于表示一些特殊字符或控制字符。在字符串前面加上反斜杠(\)可以实现转义序列的表...
    99+
    2024-04-02
  • Python 文本和数字相等判断
    文本和数字相等判断 虽然数字的字符串值被认为与整型值和浮点型值完全不同,但整型值可以与浮点值相等。Python 进行这种区分,因为字符串是文本,而整型值和浮点型都是数字。 1. example 1 Microsoft Windows [...
    99+
    2023-01-31
    数字 Python 文本和
  • python的序列遍历和字典遍历的实现方法
    这篇文章主要介绍“python的序列遍历和字典遍历的实现方法”,在日常操作中,相信很多人在python的序列遍历和字典遍历的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2024-04-02
  • python中序列的逆序方式
    目录序列的逆序方式1. range 函数2. reversed 函数3. 其他方法一个字符串的逆序函数序列的逆序方式 1. range 函数 一般 for 循环中总会用到 range...
    99+
    2024-04-02
  • python如何计算列表中数字的和
    要计算列表中数字的和,可以使用Python的内置函数`sum()`。该函数可以接受一个可迭代对象(例如列表)作为参数,并返回该可迭代...
    99+
    2023-10-10
    Python
  • 简单总结Python中序列与字典的相同和不同之处
    共同点: 1.它们都是python的核心类型,是python语言自身的一部分 核心类型与非核心类型 多数核心类型可通过特定语法来生成其对象,比如"dave"就是创建字符串类型的对象的表达式; 非核心类...
    99+
    2022-06-04
    序列 字典 不同之处
  • python序列数据类型之序列数据的基本操作
      1. 序列的长度、最大值、最小值、求和  通过内置函数len()、max() .minO可以获取序列的长度、序列中元索的最大值、序列中元素的最小值。通过内置函数sum()可以获取列表或元组中的各元素之和:如果有非数值元索,则导致TyeE...
    99+
    2023-06-02
  • 怎么在python中利用字节处理文件
    这期内容当中小编将会给大家带来有关怎么在python中利用字节处理文件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。python的数据类型有哪些python的数据类型:1. 数字类型,包括int(整型)、...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作