如果使用位元組序列構建正規表示式,\d和\w等模式只能匹配ascii字元;相比之下,如果是字串模式,就能匹配ascii之外的unicode數字或字母。
比較簡單的字串正規表示式和位元組序列正規表示式的行為
import re
re_numbers_str = re.
compile
(r'\d+'
)#➊
re_words_str = re.
compile
(r'\w+'
) re_numbers_bytes = re.
compile
(rb'\d+'
)#➋
re_words_bytes = re.
compile
(rb'\w+'
) text_str =
("ramanujan saw \u0be7\u0bed\u0be8\u0bef"
#➌ " as 1729 = 1³ + 12³ = 9³ + 10³."
)#➍
text_bytes = text_str.encode(
'utf_8'
)#➎
print
('text'
,repr
(text_str)
, sep=
'\n '
)print
('numbers'
)print
(' str :'
, re_numbers_str.findall(text_str)
)#➏
print
(' bytes:'
, re_numbers_bytes.findall(text_bytes)
)#➐
print
('words'
)print
(' str :'
, re_words_str.findall(text_str)
)#➑
print
(' bytes:'
, re_words_bytes.findall(text_bytes)
)#➒
➊ 前兩個正規表示式是字串型別。
➋ 後兩個正規表示式是位元組序列型別。
➌ 要搜尋的unicode文字,包括1729的泰公尺爾數字(邏輯行直到右括號才結束)。
➍ 這個字串在編譯時與前乙個拼接起來
➎ 位元組序列只能用位元組序列正規表示式搜尋。
➏ 字串模式r』\d+『能匹配泰公尺爾數字和ascii數字。
➐ 位元組序列模式rb』\d+『只能匹配ascii位元組中的數字。
➑ 字串模式r』\w+『能匹配字母、上標、泰公尺爾數字和ascii數字。
➒ 位元組序列模式rb』\w+'只能匹配ascii位元組中的字母和數字。
輸出
text
'ramanujan saw ௧௭௨௯ as 1729 = 1³ + 12³ = 9³ + 10³.'
numbers
str:[
'௧௭௨௯'
,'1729'
,'1'
,'12'
,'9'
,'10'
]bytes
:[b'1729'
, b'1'
, b'12'
, b'9'
, b'10'
]words
str:[
'ramanujan'
,'saw'
,'௧௭௨௯'
,'as'
,'1729'
,'1³'
,'12³'
,'9³'
,'10³'
]bytes
:[b'ramanujan'
, b'saw'
, b'as'
, b'1729'
, b'1'
, b'12'
, b'9'
, b'10'
]
分析:可以使用正規表示式搜尋字串和位元組序列,但是在後一種情況中,ascii範圍外的位元組不會當成數字和組成單詞的字母。
字串正規表示式有個re.ascii標誌,它讓\w、\w、\b、\b、\d、\d、\s和\s只匹配ascii字元。
os模組中的所有函式、檔名或路徑名引數既能使用字串,也能使用位元組序列。
如果這樣的函式使用字串引數呼叫,該引數會使用sys.getfilesystemencoding()得到的編解碼器自動編碼,然後作業系統會使用相同的編解碼器解碼。這幾乎就是我們想要的行為,與unicode三明治最佳實踐一致。
#把字串和位元組序列引數傳給listdir函式得到的結果
>>
> os.listdir(
'.')
# ➊
['abc.txt'
,'digits-of-π.txt'
]>>
> os.listdir(b'.'
)# ➋
[b'abc.txt'
, b'digits-of-\xcf\x80.txt'
]
➊ 第二個檔名是「digits-of-π.txt」(有乙個希臘字母π)。
➋ 引數是位元組序列,listdir函式返回的檔名也是位元組序列:b』\xcf\x80』是希臘字母π的utf-8編碼。
為了便於手動處理字串或位元組序列形式的檔名或路徑名,os模組提供了特殊的編碼和解碼函式。
如果filename是str型別(此外還可能是bytes型別),使用sys.getfilesystemencoding()返回的編解碼器把filename編碼成位元組序列;否則,返回未經修改的filename位元組 序列。
如果filename是bytes型別(此外還可能是str型別),使用sys.getfilesystemen- coding()返回的編解碼器把filename解碼成字串;否則,返回未經修改的filename字串。
使用surrogateescape處理鬼符
python 3.1引入的surrogateescape編解碼器錯誤處理方式是處理意外位元組序列或未知編碼的一種方式。
這種錯誤處理方式會把每個無法解碼的位元組替換成unicode中u+dc00到u+dcff之間的碼位。
#使用surrogateescape錯誤處理方式
>>
> os.listdir(
'.')
#➊ [
'abc.txt'
,'digits-of-π.txt'
]>>
> os.listdir(b'.'
)#➋
[b'abc.txt'
, b'digits-of-\xcf\x80.txt'
]>>
> pi_name_bytes = os.listdir(b'.')[
1]#➌ >>
> pi_name_str = pi_name_bytes.decode(
'ascii'
,'surrogateescape'
)#➍
>>
> pi_name_str #➎
'digits-of-\udccf\udc80.txt'
>>
> pi_name_str.encode(
'ascii'
,'surrogateescape'
)#➏
b'digits-of-\xcf\x80.txt'
➊ 列出目錄裡的檔案,有個檔名中包含非ascii字元。
➋ 假設我們不知道編碼,獲取檔名的位元組序列形式。
➌ pi_names_bytes是包含π的檔名。
➍ 使用』ascii』編解碼器和』surrogateescape』錯誤處理方式把它解碼成字串。
➎ 各個非ascii位元組替換成代替碼位:』\xcf\x80』變成了』\udccf\udc80』。
➏ 編碼成ascii位元組序列:各個代替碼位還原成被替換的位元組。
字串和位元組
python3中只有一種能夠儲存文字資訊的資料型別,就是str string,子字串 它是不可便序列,儲存的是unicode碼位 code point 這是與python2的主要區別,python2用str表示位元組字串,這種型別在python3中用bytes物件來處理 但處理方式並不完全相同 py...
字串 字元和位元組
字串是由乙個個字元組成的,每個字元又由乙個或多個位元組來表示,每個位元組又由8個bit位來表示。字元 計算機中使用的文字和符號,比如1 2 a b 等等。位元組 byte 一種計量單位,表示資料量多少,它是計算機資訊技術用於計量儲存容量的一種計量單位。不同編碼裡,字元和位元組的對應關係不同 asci...
字串 字元和位元組
字串就是一串零個或多個字元,並且以乙個位模式為全0的nul位元組結尾。nul位元組是字串的終止符,但是它本身不是字串的一部分,所以字串的長度並不包括nul位元組。標頭檔案string.h包含了使用字串函式所需的原型和宣告。字串的長度就是它所包含的字元個數。strlen可求字串長度,返回值是size ...