1. 程式人生 > >python 學習彙總41:unicode( tcy)

python 學習彙總41:unicode( tcy)

Unicode   2018/7/1

1.字元

一般字元:

'a';'嚴';
特殊字元:
編輯器中不能直接輸入,在字串文字中使用轉義序列
\u轉義序列編寫特定的Unicode程式碼點

'\u0394' # 'Δ' 16-bit hex value
"\U00000394 # 'Δ' 32-bit hex value
"\N{GREEK CAPITAL LETTER DELTA}" # 希臘大寫字母Delta :'Δ'
répertoire = "trouvé" #可將Unicode字元包含在字串文字,識別符號中。
2.Unicode
2.1. 字符集:
只是一個“字符集”,它給每一個處於此字符集中的字元給予了一個編號。
Unicode 標準描述瞭如何用 程式碼點 表示字元。程式碼點是一個整數值通常用16 進製表示。
Unicode標準包含很多列出字元及其相應程式碼點的表格:

0061 'a'; LATIN SMALL LETTER A
0062 'b'; LATIN SMALL LETTER B
0063 'c'; LATIN SMALL LETTER C
...
007B '{'; LEFT CURLY BRACKET

一個Unicode字串是一系列程式碼點,從0到0x10FFFF的數字。
該序列需要表示為記憶體中的一組位元組(意思是從0到255的值)。
將Unicode字串轉換為位元組序列的規則稱為編碼。
        ord('a')                                            # 97
        hex(ord("嚴"))= '0x4e25'                #"嚴"unicode程式碼點=4E25
        ord('\u0394')   #等價於:ord('Δ')    #返回程式碼點值:=916

        逆轉換:
        chr(916)        #等價於:chr(0x394) #10進位制的916=16進位制的394 #返回單字元'Δ'
        chr(97)          #等價於:chr(0x61)   #10進位制的97=16進位制的61     #返回單字元'a'

   2.2.編碼方案 utf-8
        指定字元以什麼位元組序儲存和傳輸
        將Unicode字串轉換為位元組序列的規則稱為編碼。
        編碼一定,位元組序一定,儲存結果是肯定要落實到位元組(Bytes)上來的。

     編碼:
        'a'.encode('utf-8')         # b'a' 返回Unicode字串的bytes
        "嚴".encode()              #b'\xe4\xb8\xa5'
        'Δ'.encode('utf-8')        # b'\xce\x94'
        解碼:
        b'a'.decode()                      # 'a'
        b'\xe4\xb8\xa5'.decode()  #"嚴"
        b'\xce\x94'.decode()         # 'Δ' 
3.指定程式碼編碼:程式碼前2行
# -*- coding: <encoding name> -*-
獲取系統編碼:
import sys
sys.getfilesystemencoding()# 'utf-8
4.例項:
例項1.-編碼str.encode()
str.encode            返回Unicode字串的bytes
        引數:
       strict
            ignore
            replace                  插入問號
            xmlcharrefreplace  插入XML字元引用
            backslashreplace   插入\uNNNN轉義序列
            namereplace          插入\N

        例項:
            u = chr(40960) + 'abcd' + chr(1972)
            u.encode('utf-8')                                     # b'\xea\x80\x80abcd\xde\xb4'

            u.encode('ascii')                                     #錯誤
            u.encode('ascii', 'ignore')                      # b'abcd'
            u.encode('ascii', 'replace')                    # b'?abcd?'
            u.encode('ascii', 'xmlcharrefreplace') # b'&#40960;abcd&#1972;'
            u.encode('ascii', 'backslashreplace')  # b'\\ua000abcd\\u07b4'
            u.encode('ascii', 'namereplace')          # b'\\N{YI SYLLABLE IT}abcd\\u07b4'

例項2.-解碼bytes.decode()

            b'\x80abc'.decode("utf-8", "strict")                      #錯誤
            b'\x80abc'.decode("utf-8", "replace")                  # '\ufffdabc'
            b'\x80abc'.decode("utf-8", "backslashreplace") # '\\x80abc'
            b'\x80abc'.decode("utf-8", "ignore")                    #'abc'
例項3-ord(),chr():
       ord() #接受一個字元的Unicode字串並返回程式碼點值
                以一個字元(長1字串8位)作為引數,返回對應的 ASCII值或Unicode值
                如給Unicode字元超出範圍引發TypeError

            chr()#用一位元組整數作引數返回對應字元。
                建立單字元Unicode字串,該函式使用整數並返回包含相應程式碼點的長度為1的Unicode字串。

            chr(57344)   # '\ue000'
            ord('\ue000')# 57344
5.備註:
5.1.Unicode屬性
字元資訊包括字元的名稱,類別,數值
# 顯示一些關於幾個字元的資訊,並列印一個特定字元的數字值:
import unicodedata

u = chr(233) + chr(0x0bf2) + chr(3972) + chr(6000) + chr(13231)
for i, c in enumerate(u):
print(i, '程式碼點=%04x ;程式碼=' % ord(c), unicodedata.category(c), end=" ")#類別程式碼:是描述角色性質的縮寫。
print('; 名稱=',unicodedata.name(c))
# Get numeric value of second character
print(unicodedata.numeric(u[1]))#1000.0

# 0 程式碼點=00e9 ;程式碼= Ll ; 名稱= LATIN SMALL LETTER E WITH ACUTE# 'Ll'意思是“Letter,小寫”
# 1 程式碼點=0bf2 ;程式碼= No ; 名稱= TAMIL NUMBER ONE THOUSAND# 'No'意思是“Number,other”
# 2 程式碼點=0f84 ;程式碼= Mn ; 名稱= TIBETAN MARK HALANTA# 'Mn'是“Mark,nonspacing”
# 3 程式碼點=1770 ;程式碼= Lo ; 名稱= TAGBANWA LETTER SA
# 4 程式碼點=33af ;程式碼= So ; 名稱= SQUARE RAD OVER S SQUARED# 'So'是“Symbol,other”

===================================================================
5.2.Unicode正則表示式
re模組支援的正則表示式可以以位元組或字串的形式提供。

\d將匹配[0-9]位元組中的字元,但字串中的字元將匹配該'Nd'類別中的任何字元
\w匹配各種各樣的Unicode字元,但只能[a-zA-Z0-9_]以位元組或如果re.ASCII提供
\s並將匹配Unicode空白字元或 。[ \t\n\r\f\v]

import re
p = re.compile(r'\d+')
s = "Over \u0e55\u0e57 57 flavours"
m = p.search(s)
print(repr(m.group()))
===================================================================
5.3.讀寫Unicode資料
open('unicode.txt', encoding='utf-8')
Unicode字元U+FEFF用作位元組順序標記(BOM),通常寫為檔案的第一個字元,以幫助自動檢測檔案的位元組排序。

Unicode檔名
filename = 'filename\u4500abc'
open(filename, 'w')

            os模組中的函式os.stat()也將接受Unicode檔名。
            該os.listdir()函式返回檔名
            # utf-8 返回Unicode版本的檔名,返回包含編碼版本的位元組。

       fn = 'filename\u4500abc'
            f = open(fn, 'w')
            f.close()
            import os
            print(os.listdir(b'.'))
            print(os.listdir('.'))

            #輸出:
            amk:~$ python t.py
                     [b'filename\xe4\x94\x80abc', ...]#包含UTF-8編碼的檔名
            ['filename\u4500abc', ...]            #第二個列表包含Unicode版本

    注意
            在大多數情況下,應使用Unicode API。位元組API只能用於不可解碼檔名的系統,例如Unix系統。
====================================================================
5.4.編寫支援Unicode的程式的技巧

    在檔案編碼之間轉換
            StreamRecoder類可以在編碼之間透明轉換
            # 例如輸入檔案f是Latin-1,返回以UTF-8編碼位元組:
            new_f = codecs.StreamRecoder(f,
                                    # en/decoder: used by read() to encode its results and by write() to decode its input.
                                    codecs.getencoder('utf-8'), codecs.getdecoder('utf-8'),
                                    # reader/writer: used to read and write to the stream.
                                    codecs.getreader('latin-1'), codecs.getwriter('latin-1') )

        未知編碼中的檔案
            對檔案進行更改不知道檔案編碼,知道編碼與ASCII相容,並只想檢查或修改ASCII部分,
            用surrogateescape錯誤處理程式開啟該檔案:

       with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
            data = f.read()
            # make changes to the string 'data'
            with open(fname + '.new', 'w',encoding="ascii", errors="surrogateescape") as f:
                f.write(data)
            surrogateescape錯誤處理程式將所有非ASCII位元組解碼為Unicode的專用使用區域範圍從U + DC80到U + DCFF程式碼點。
            surrogateescape當編碼資料並將其寫回時使用錯誤處理程式時,這些私有程式碼點將被重新轉換為相同的位元組。