Python字符串编码——UnicodeASCII, Unicode, UTF-8

by admin on 2018年10月9日

ASCII码

我们理解,在电脑中,所有的信最终还代表为一个二进制的字符串。每一个二进制位(bit)有0和1鲜种植状态,因此八只二进制位就可以构成出256栽状态,这让喻为一个字节(byte)。也就是说,一个字节一共可以用来表示256栽不同之状态,每一个状态对应一个符号,就是256个号,从0000000到11111111。
上个世纪60年代,美国制定了千篇一律仿字符编码,对英语字符与二进制位之间的涉嫌,做了统一规定。这被称之为ASCII码,一直沿用至今。
ASCII码一共规定了128单字符的编码,比如空格”SPACE”是32(二迈入制00100000),大写的字母A是65(二前行制01000001)。这128单记号(包括32单不可知打印出来的支配符号),只占了一个字节的后面7员,最前边的1位统一规定为0。

本文参考:http://www.ruanyifeng.com/blog/2007/10/ascii\_unicode\_and\_utf-8.html)

非ASCII编码

英语用128只标志编码就够了,但是用来表示其余语言,128个号是不够的。比如,在法语中,字母上方有注音符号,它就是无法用ASCII码表示。于是,一些欧洲江山虽控制,利用字节中不了了之的高位编入新的符号。比如,法语中之é的编码为130(二进制10000010)。这样一来,这些欧洲国度以的编码体系,可以象征最多256单标志。

但,这里又出现了新的题目。不同之国度有两样之假名,因此,哪怕它还使用256只标志的编码方式,代表的字母却休平等。比如,130在法语编码中意味了é,在希伯来语编码中可代表了字母Gimel
(ג),在俄语编码中同时见面表示任何一个记。但是无论如何,所有这些编码方式中,0–127意味的标志是相同的,不同等的就是128–255之即无异段落。

有关亚洲国的文,使用的标记就再次多矣,汉字就是大多上10万横。一个字节只能表示256栽标志,肯定是不够的,就必利用多个字节表达一个标志。比如,简体中文常见的编码方式是GB2312,使用有限单字节表示一个中国字,所以理论及极其多足表示256×256=65536单记号。

华语编码的问题用专文讨论,这首笔记不涉。这里只有指出,虽然还是因此多单字节表示一个号,但是GB类的汉字编码与后文的Unicode和UTF-8是毫无关系的。

1. ASCII码

Unicode

正好使齐亦然省所说,世界上有正在多编码方式,同一个二进制数字可以为说成不同之标记。因此,要想打开一个文件文件,就亟须掌握她的编码方式,否则用错误的编码方式解读,就见面油然而生乱码。为什么电子邮件时出现乱码?就是盖发信人和收信人使用的编码方式不雷同。

可想像,如果来同样种植编码,将世界上有的记都纳入其间。每一个标记都给予一个无比的编码,那么乱码问题就会见没有。这即是Unicode,就像其的名字都意味着的,这是相同种有符号的编码。

Unicode当然是一个挺充分之成团,现在的规模得以容纳100差不多万独号。每个符号的编码还不等同,比如,U+0639意味着阿拉伯字母Ain,U+0041意味英语的死去活来写字母A,U+4E25表示汉字”严”。具体的号对应表,可以查询unicode.org,或者特别的方块字对应表。

咱们懂得,在电脑中,所有的信息最终还代表为一个二进制的字符串。每一个二进制位(bit)有0和1星星种植状态,因此八只二进制位就得组合有256栽状态,这让誉为一个字节(byte)。也就是说,一个字节一共可以就此来表示256种不同的状态,每一个态对应一个标志,就是256独记,从0000000到11111111。

Unicode的问题

亟需留意的是,Unicode只是一个标记集,它仅仅规定了号的老二向前制代码,却没规定是二进制代码应该如何存储。

比如,汉字”严”的unicode是十六上制数4E25,转换成二上制数足足有15位(100111000100101),也就是说这个标记的代表至少需要2单字节。表示其余更可怜之符,可能要3只字节或者4独字节,甚至更多。

此间就是生个别单重的题目,第一只问题是,如何才能够分别Unicode和ASCII?计算机怎么知道老三个字节表示一个标志,而未是分别表示三只标志为?第二只问题是,我们曾经掌握,英文字母只所以一个字节表示虽足足了,如果Unicode统一规定,每个符号用三只或四独字节表示,那么每个英文字母前还定产生次届三只字节是0,这对于仓储来说是翻天覆地的浪费,文本文件的大小会用大出二三倍增,这是无能为力承受之。

她造成的结果是:1)出现了Unicode的强囤积方,也就是说有许多种不同的第二上制格式,可以用来代表Unicode。2)Unicode在非常丰富一段时间内无法放开,直到互联网的面世。

上个世纪60年代,美国制订了千篇一律仿字符编码,对英语字符与二进制位之间的涉及,做了统一规定。这叫名ASCII码,一直沿用至今。

UTF-8

互联网的推广,强烈要求出现一样栽统一的编码方式。UTF-8就是于互联网及使最广大的一致种Unicode的落实方式。其他实现方式还包UTF-16(字符用少单字节或四只字节表示)和UTF-32(字符用四独字节表示),不过以互联网及着力不用。重复雷同尽,这里的干是,UTF-8是Unicode的兑现方式有。

UTF-8最充分之一个特性,就是它是同一种植变长的编码方式。它好下1~4个字节表示一个号,根据不同的标志而变化字节长度。
UTF-8的编码规则不行粗略,只来次长:

1)对于单字节的符号,字节的首先各类如为0,后面7各项也这标记的unicode码。因此对于英语字母,UTF-8编码和ASCII码是同之。

2)对于n字节的记号(n>1),第一只字节的眼前n位都设为1,第n+1位设为0,后面字节的前片个一律要为10。剩下的无提及的二进制位,全部乎这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的号。

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)

——————–+———————————————

0000 0000-0000 007F | 0xxxxxxx

0000 0080-0000 07FF | 110xxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

跟据上表,解读UTF-8编码非常简单。如果一个字节的首先各类是0,则是字节单独就是一个字符;如果第一各是1,则总是有微微只1,就代表目前字符占用小个字节。

脚,还是以汉字”严”为例,演示如何促成UTF-8编码。

早已清楚”严”的unicode是4E25(100111000100101),根据上表,可以发现4E25介乎第三推行之克外(0000
0800-0000 FFFF),因此”严”的UTF-8编码需要三个字节,即格式是”1110xxxx
10xxxxxx
10xxxxxx”。然后,从”严”的末梢一个二进制位开始,依次从后上填入格式中之x,多出底号补0。这样尽管取得了,”严”的UTF-8编码是”11100100
10111000 10100101″,转换成为十六进制就是E4B8A5。

ASCII码一共规定了128独字符的编码,比如空格”SPACE”是32(二上前制00100000),大写的字母A是65(二前进制01000001)。这128独记(包括32个未可知打印出来的支配符号),只占了一个字节的末端7号,最前边的1位统一规定为0。

python 中之字符串编码

在使用

#!/usr/bin/env python
# -*- coding:utf-8 -*-

默认的汉语编码为utf8

>>> kel = '中' 
>>> kel
'\xe4\xb8\xad'

加入u以后,变成unicode

>>> kel = u'中'
>>> kel
u'\u4e2d'

2、非ASCII编码

python 文件字符串编码

保存Unicode字符到文本文档

#coding=utf-8
import os

def write_use_open(filepath):
    try:
        file = open(filepath, 'wb')
        try:
            content = '中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
            print file.encoding
            print file.newlines
            print file.mode
            print file.closed
            print content
            file.write(content)
        finally:
            file.close()
            print file.closed
    except IOError, e:
        print e


if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    write_use_open(filepath)

初始自己是IDLE编写的,并直接按F5运行,没察觉题目,文件为于科学地保留,文件的编码类型为是utf-8.

但是我用命令执行运行,却发现显示出现乱码了,然后于开拓文件发现文件为科学保存了,编码还是utf-8:

亚洲必赢手机入口 1

题目是令执行不可知自动识别字符编码吧,因为IDLE显示是无可非议的,它支持utf-8。

乃我修改了代码,在字符串前加了’u’,表明content是unicode:
content = u’中华人民共和国abcd \r\nee
?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n’

可是运行发现,命令行是正确显示了,但是也出现异常:

亚洲必赢手机入口 2

颇引人注目,content里噙了非ASCII码字符,肯定不可知以ASCII来展开编码的,write方法是默认使用ascii来编码保存之。

深容易就足以想到,在保留之前,先对unicode字符进行编码,我选择utf-8

#coding=utf-8
import os

def write_use_open(filepath):
    try:
        file = open(filepath, 'wb')
        try:
            content = u'中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
            print file.encoding
            print file.newlines
            print file.mode
            print file.closed
            print content
            print unicode.encode(content, 'utf-8')
            file.write(unicode.encode(content, 'utf-8'))
        finally:
            file.close()
            print file.closed
    except IOError, e:
        print e

if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    write_use_open(filepath)

探运行结果:

亚洲必赢手机入口 3

OK了打开文档也是科学的。
读取文件同时怎么?同样道理,只是这次未是编码了,而解码:

def read_use_open(filepath):
    try:
        file = open(filepath, 'rb')
        try:
            content = file.read()
            content_decode = unicode(content, 'utf-8')
            print 'original text'
            print content
            print 'decode using utf-8'
            print content_decode
        finally:
            file.close()
    except IOError, e:
        print e

if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    write_use_open(filepath)
    print 'read file ---------------------------'
    read_use_open(filepath)

亚洲必赢手机入口 4

怎不直在open的时就解码呢?呵呵,可以啊,可以采取codecs的open方法

import codecs
def read_use_codecs_open(filepath):
    try:
        file = codecs.open(filepath, 'rb', 'utf-8')
        try:
            print 'using codecs.open'
            content = file.read()
            print content
        finally:
            file.close()
    except IOError, e:
        print e

亚洲必赢手机入口 5

英语用128单记号编码就够了,但是用来表示其余语言,128个号是不够的。比如,在法语中,字母上方有注音符号,它就是无法用ASCII码表示。于是,一些欧洲国度虽控制,利用字节中不了了之的高位编入新的标志。比如,法语中之é的编码为130(二进制10000010)。这样一来,这些欧洲国度以的编码体系,可以象征最多256单标志。

纱中乱码的解决

汉语网页遭到,有些网页抓取下来后,由于网页编码的题材,需要开展解码。首先我们用判定网页中到底使用的是什么编码,在根据这个编码把字符串变成utf8编码。

每当探测编码时,chardet第三方库非常之有益。

网页编码判断:

import urllib
rawdata = urllib.urlopen('http://tech.163.com/special/00097UHL/tech_datalist.js').read()
import chardet
print chardet.detect(rawdata)

{'confidence': 0.99, 'language': 'Chinese', 'encoding': 'GB2312'}

由此 chardet
探测有,网页的字符编码为GB2312编码,通过unicode转化为utf8编码:

str_body = unicode(rawdata, "gb2312").encode("utf8")

更多入门教程可以参照:[http://www.bugingcode.com/python_start/]
(http://www.bugingcode.com/python_start/)

然,这里以并发了初的题材。不同的国有两样之假名,因此,哪怕它还用256个号的编码方式,代表的字母却不雷同。比如,130于法语编码中象征了é,在希伯来语编码中也代表了配母Gimel
(ג),在俄语编码中还要会表示任何一个标志。但是无论如何,所有这些编码方式中,0–127意味着的标记是均等的,不等同的无非是128–255的就无异段落。所以,在128–255立马段受到,同一个次前行制数在不同国度的文被象征不同之字符。

关于亚洲江山之仿,使用的标记就再也多了,汉字就是大多上10万左右。一个字节只能表示256种植标志,肯定是不够的,就亟须动多只字节表达一个记。比如,简体中文常见的编码方式是GB2312,使用简单只字节表示一个中国字,所以理论及无与伦比多足表示256×256=65536单标志。

华语编码的问题亟需专文讨论,这首笔记不干。这里就指出,虽然还是故几近只字节表示一个号,但是GB类的汉字编码与后文的Unicode和UTF-8是毫无关系的。

3.Unicode

刚而齐一样省所说,世界上是正在多编码方式,同一个二进制数字可以让分解成不同的记号。因此,要想打开一个文本文件,就亟须掌握它们的编码方式,否则用错误的编码方式解读,就见面面世乱码。为什么电子邮件时出现乱码?就是以发信人和收信人使用的编码方式不一致。

可想象,如果发生同等种编码,将世界上享有的号子都纳入其间。每一个记都给以一个旷世之编码,那么乱码问题便会化为乌有。这就算是Unicode,就如她的名还代表的,这是平种植有符号的编码。

Unicode当然是一个特别特别之联谊,现在底局面得以容纳100多万只标志。每个符号的编码还未均等,比如,U+0639代表阿拉伯字母Ain,U+0041意味着英语的酷写字母A,U+4E25代表汉字”严”。具体的标志对应表,可以查询unicode.org,或者特别的字对应表。

4. Unicode的问题

要小心的是,Unicode只是一个符号集,它只是确定了符的亚上制代码,却尚未规定者二进制代码应该怎样存储。

遵,汉字”严”的unicode是十六向前制数4E25,转换成为二迈入制数足足有15各类(100111000100101),也就是说这个标记的代表至少需2单字节。表示其余还甚之记,可能用3个字节或者4个字节,甚至又多。

此间就是出有限独重的题目,第一个问题是,如何才会分Unicode和ASCII?计算机怎么掌握老三个字节表示一个标记,而非是个别代表三只记为?第二独问题是,我们早已亮,英文字母只所以一个字节表示即够用了,如果Unicode统一确定,每个符号用三单或四只字节表示,那么每个英文字母前都定发生次届三单字节是0,这对仓储来说是大的荒废,文本文件之分寸会因此大出二三倍增,这是无力回天承受的。

其造成的结果是:1)出现了Unicode的多种囤方,也就是说有许多种不同的亚上前制格式,可以就此来表示Unicode。2)Unicode在特别丰富一段时间内无法放开,直到互联网的面世。

5.UTF-8

互联网的推广,强烈要求出现雷同种植统一的编码方式。UTF-8就是以互联网上以最普遍的均等种Unicode的贯彻方式。其他实现方式还包UTF-16(字符用鲜只字节或四独字节表示)和UTF-32(字符用四单字节表示),不过以互联网及基本不用。重新同一满,这里的涉是,UTF-8凡Unicode的落实方式之一。

UTF-8最要命的一个特性,就是它们是一样种变长的编码方式。它可行使1~4个字节表示一个符号,根据不同之符号而变化字节长度。

UTF-8的编码规则不行简单,只发生次久:

1)对于单字节的符号,字节的高位设为0,后面7各类也这标记的unicode码。因此对英语字母,UTF-8编码和ASCII码是平等的。

2)对于n字节的标记(n>1),第一单字节的前面n位都要为1,第n+1位设为0,后面字节的前方少号一律要为10。剩下的远非提及的二进制位,全部吗夫符号的unicode码。

下表总结了编码规则,字母x表示可用编码的号。

Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
——————–+———————————————
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

 

跟据上表,解读UTF-8编码非常简单。如果一个字节的首先各项是0,则是字节单独就是一个字符;如果第一员是1,则总是发生多少个1,就象征目前字符占用小只字节。

脚,还是坐汉字”严”为条例,演示如何兑现UTF-8编码。

就解”严”的unicode是4E25(100111000100101),根据上表,可以窥见4E25处于第三履行之限量外(0000
0800-0000 FFFF),因此”严”的UTF-8编码需要三独字节,即格式是”1110xxxx
10xxxxxx
10xxxxxx”。然后,从”严”的最终一个二进制位开始,依次从后上填入格式中的x,多起的各类补0。这样就算落了,”严”的UTF-8编码是”11100100
10111000 10100101″,转换成为十六进制就是E4B8A5。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图