ASCII編碼
電腦是美國人發明的, 所以當初他們只把英文字母及一些符號數字進行編碼, 產生了127個ASCII的編碼原則. 比如
A : 65
a : 97
0 : 48
空格 : 32
Unicode編碼
到了中文, 日文等複雜的語系時, 127個編碼當然不夠使用, 此時就需使用二個byte以上來表示這些語言.
但各國有各自的編碼原則, 比如中文就有繁体BIG5及簡体的GB2312編碼. 而全世界上百種語言, 這樣在多國語言混合時, 就產生了衝突而顯示出亂碼來.
為了解決多國語言的問題, Unicode因此而生. 通常採用2個byte表示一個字. 當然, 不是固定只有2 byte, 遇到比較偏門的文字, 還是會用到4 byte及6 byte。
比如 “中” 這個字, 在Unicode 的編碼就是 20013
UTF-8編碼
使用Unicode可以解決亂碼問題. 但也衍生了另一個問題. 以A而言, Unicode也是65, 不過確是佔了2個byte, 所以二進位為 00000000 01000001 , 前八碼都為 0, 這樣顯然浪費了一些空間. 而如果文件中大部份都是英文的話, 那浪費的空間就更多了.
為了解決上述問題, 新的utf-8編碼方式得以產生. utf-8採可變動長度的編碼方式. 比如是英文時, 就採用1 byte, 中文就採用3 byte, 偏門字就採4 – 6 byte. 通常用於低速儲存裝置或網路傳輸上. 比如web server就會將動態生存的Unicode, 先轉碼成utf-8, 再傳輸到網路上, 然後在瀏覽器上也是以utf-8顯示出來.
Python支援
Python 3使用Unicode編碼方式. 比如 print(‘這是中文字串’), 印出來的就是中文的字串.
另外Python提供二個函數進行轉換
ord(‘中’) : 將字元轉成Unicode
chr(20013) : 將Unicode轉成字元
print("Unicode : ",ord('中')) print("字元 : ", chr(20013)) 結果如下 Unicode : 20013 字元 : 中
如果知道字元的 16 進位 Unicode, 也可以使用 \uXXXX來表示字元, 如下
a="\u4e2d\u6587" print(a)
轉碼
字串轉byte–encode
Python處理字串時採用Unicode, 但若要傳輸到網路上, 或儲存在硬碟上, 則要轉成byte.
字串如果只有英文, 比如 a=”ABC”, 則可以使用 “b” 前綴字改成以ascii為編碼的byte資料, 如 a=b”ABC”. 此時把a印出來, 雖然也是印出ABC, 但前面有加上 b, 表示傳輸出去的, 是以 byte為主的。
如果字串有中文的話, 比如a=”中文測試”, 加上前綴字如下 : a=b”中文測試”, 此時因為中文是無法轉成ascii的, 所以會發生錯誤 : SyntaxError: bytes can only contain ASCII literal characters.
那怎麼轉成byte呢?? 當然, 需跟電腦說明要轉成什麼碼. 使用 “ABC”.encode(“utf-8″). encode需指定轉碼格式, 如”utf-8”, “big5”. 從下面的例子可得知, utf-8使用 3byte, big5使用 2 byte‧
a="中文".encode("big5") print("big5 : ", a, "每個字使用 2byte") a="中文".encode("utf-8") print("utf-8 : ", a, "每個字使用 3byte") 結果如下 big5 : b'\xa4\xa4\xa4\xe5' 每個字使用 2byte utf-8 : b'\xe4\xb8\xad\xe6\x96\x87' 每個字使用 3byte
btye轉字串 – decode()
相對的, 如果要網路或硬碟讀取進來的, 是byte的資料格式, 此時就需使用decode()解碼成字串
a=b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8') print(a) 結果 中文
如果bytes中包含了無法解碼的字元, decode()就會回報錯誤 : UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
如果bytes中只有一小部份是無效的字元, 可以使用errors=’ignore’ 參數忽略錯誤的字元.
a=b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore') print(a) 結果 : 中
len()
len()參數如果為字串, 則計算字串長度. 如果為bytes, 則計算有幾個 byte, 如下
print(len("中文")) <== 結果為 2 print(len("中文".encode("utf-8"))) <== 結為 6
標示編碼
程式碼中, 為了標示本程式採用utf-8, 通常會於開頭撰寫如下二行
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行只對Linux有效, Windows無效. 第二行則標示為 utf-8. 另如果使用notepad++時, 請記得以而將檔案編碼方式改為 UTF-8 without BOM
格式化
若要印出 — 單價 : 100, 數量 : 10, 總價 : 1000
則可以使用跟C語言一樣的格式化列印
%d: 整數
%f : 小數
%s : 字串
%x : 16進位
上述也可標示列印位數, 如 %.2f, 表示只印二位小數
如下所示
price=10.6 qty=10 print("單價 : %.2f, 數量 : %d, 總價 : %f" % (price, qty, price*qty))
若要列印 “%”, 則必需寫成如下
print("%.2f%%" % 10.6)
Format
format是另一種格式化的方式, 可以在字串中使用 {0}, {1} 的格式, 然後將要取代的字串, 由 format()的參數取得, 有點像C#的寫法. format為字串的物件方法
a="單價 : {0}, 數量 : {1}, 總價 : {2}".format(price, qty, price*qty)
print(a)
其他編碼
Python除了可以編碼成utf-8之外, 也可編碼成big5, GB2313. 但轉成其他的編碼只是突增困擾而以.
replace
replace可以將某個字元給取代. 請注意, 因為字串是不可變的, 所以如下的寫法, 還是 “abc”.
如果寫成 a=a.replace(‘a’, ‘A’), 印出來才會是Abc
a = 'abc' a.replace('a', 'A') print(a) 結果 abc
字串相加
可用 “+” 或 __add__()函數
a="abc" b="def" c=a+b d=a.__add__(b) print(c) print(d)
高效字串相加
上述使用 + 相加, 其效能非常的差. 高效方法如下
strlist=[]
strlist.append('first')
strlist.append('second')
strlist.append('third')
strlist.append('forth')
str=''.join(strlist)
請注意, 一定要用 ”.join , 若使用 ‘xxx’.join(strlist), 則會產生 firstxxxsecond……, xxx會插入到第二個位置
split
將定串依指定字串拆開, 並傳回List
如果字串有二個 ‘,’ 所以如果依 ‘,’ 拆開, 就會產生三個元素的List, 第二個字串為空字串
print('Thomas,,彰化市中山路一段1號'.split(',')) 結果: ['Thomas', '', '彰化市中山路一段1號']
index
a='Thomas 彰化市中山路一段1號' print(a.index('一段')) 結果 : 13
子字串
‘ABCDEFGHIJKLM'[啟始位置:結束位置],
啟始位置的字串索引編號由 0 開始(‘A’ 的編號為0)
結束位置由字串索引編號由 1 開始(‘A’ 的編號為1)
a='ABCDEFGHIJKLM' print(a[1:3]) 結果 : BC
字串自動補0
t='123' t=t.zfill(5) print(t) 結果為 : 00123