上一篇文章:Python實用技法第27篇:編寫多行模式的正規表示式
下一篇文章:Python實用技法第29篇:用正規表示式處理Unicode字元
1、需求?
我們正在同Unicode字串打交道,但需要確保所有的字串都擁有相同的底層表示。
2、解決方案?
在Unicode中,有些特定的字元可以被表示成多種合法的程式碼點序列。為了說明這個問題,請看下面示例:
str1=`u00f1`
str2=`nu0303`
str3=`u0303`
print(str1)
print(str2)
print(str3)
print(str1==str2)
print(len(str1))
print(len(str2))
執行結果:
ñ
ñ
̃
False
1
2
這裡的文字ñ是以兩種形式呈現:
- 第一種使用的是字元ñ的【全組成】形式:U+00F
- 第二種使用的是拉丁字母n緊跟著一個“~”,【組合】而成的字元:U+0303
對於一個比較字串的程式來說,同一個文字擁有多種不同的表示形式是個大問題。為了解決這個問題,應該先將文字同一表示為規範形式,這可以通過unicodedata模組來完成。
例項:
import unicodedata
str1=`u00f1`
str2=`nu0303`
t1=unicodedata.normalize(`NFC`,str1)
t2=unicodedata.normalize(`NFC`,str2)
print(t1)
print(t2)
print(t1==t2)
print(len(t1))
print(len(t2))
print(`*`*10)
t3=unicodedata.normalize(`NFD`,str1)
t4=unicodedata.normalize(`NFD`,str2)
print(t3)
print(t4)
print(t3==t4)
print(len(t3))
print(len(t4))
結果:
ñ
ñ
True
1
1
**********
ñ
ñ
True
2
2
normalize()的第一個引數指定了字串應該如何完成規範表示。
- NFC表示字串應該是【全組成】的(即,如果可能的話使用單個程式碼點)。
- NFD表示應該使用【組合】字元,每個字元應該是能完全分解的。
Python還支援NFKC和NFKD的規範表示形式,它們為處理特定型別的字元增加額額外的相容功能。
例項:
import unicodedata
str=`ufb01`
print(str)
print(len(str))
print(`*`*10)
t_nfd=unicodedata.normalize(`NFD`,str)
t_nfkd=unicodedata.normalize(`NFKD`,str)
t_nfc=unicodedata.normalize(`NFC`,str)
t_nfkc=unicodedata.normalize(`NFKC`,str)
print(t_nfd)
print(len(t_nfd))
print(`*`*10)
print(t_nfkd)
print(len(t_nfkd))
print(`*`*10)
print(t_nfc)
print(len(t_nfc))
print(`*`*10)
print(t_nfkc)
print(len(t_nfkc))
執行結果:
fi
1
**********
fi
1
**********
fi
2
**********
fi
1
**********
fi
2
3、分析?
對於任何需要確保以規範和一致性的方式進行處理Unicode文字的程式來說,規範化都是重要的一部分。尤其是在處理使用者輸入時接收到的字串時,此時你無法控制字串的編碼方式,那麼規範化文字的表示就顯得更為重要了。
在對文字進行過濾和淨化時,規範化同樣也佔據了重要的部分。例如,假設想從某些文字中去除所有的音符標記(可能是為了進行搜尋或匹配):
import unicodedata
str=`啦啦啦ufb01我是測試u00f1呱呱呱nu0303`
t1=unicodedata.normalize(`NFD`,str)
print(str)
print(t1)
#使用combining()函式判斷指定內容是否為一個組合型字元。
result=``.join(x for x in t1 if not unicodedata.combining(x))
print(result)
執行結果:
啦啦啦fi我是測試ñ呱呱呱ñ
啦啦啦fi我是測試ñ呱呱呱ñ
啦啦啦fi我是測試n呱呱呱n
很顯然,Unicode是一個龐大的主題,要獲得更多相關內容,可以參考:
http://www.unicode.org/faq/no…
https://nedbatchelder.com/tex…
上一篇文章:Python實用技法第27篇:編寫多行模式的正規表示式
下一篇文章:Python實用技法第29篇:用正規表示式處理Unicode字元