Python實用技法第28篇:將Unicode文本統一表示爲規範形式

上一篇文章: Python實用技法第27篇:編寫多行模式的正則表達式
下一篇文章: Python實用技法第29篇:用正則表達式處理Unicode字符

一、需求🙀

咱們正在同Unicode字符串打交道,但須要確保全部的字符串都擁有相同的底層表示。

二、解決方案😸

在Unicode中,有些特定的字符能夠被表示成多種合法的代碼點序列。爲了說明這個問題,請看下面示例:html

str1='\u00f1'
str2='n\u0303'
str3='\u0303'

print(str1)
print(str2)
print(str3)

print(str1==str2)
print(len(str1))
print(len(str2))

運行結果:正則表達式

ñ
ñ
̃
False
1
2

這裏的文本ñ是以兩種形式呈現:segmentfault

  • 第一種使用的是字符ñ的【全組成】形式:U+00F
  • 第二種使用的是拉丁字母n緊跟着一個「~」,【組合】而成的字符:U+0303

對於一個比較字符串的程序來講,同一個文本擁有多種不一樣的表示形式是個大問題。爲了解決這個問題,應該先將文本同一表示爲規範形式,這能夠經過unicodedata模塊來完成。函數

實例:測試

import unicodedata
str1='\u00f1'
str2='n\u0303'

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()的第一個參數指定了字符串應該如何完成規範表示。code

  • NFC表示字符串應該是【全組成】的(即,若是可能的話使用單個代碼點)。
  • NFD表示應該使用【組合】字符,每一個字符應該是能徹底分解的。

Python還支持NFKC和NFKD的規範表示形式,它們爲處理特定類型的字符增長額額外的兼容功能。orm

實例:htm

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))

運行結果:ip

fi
1
**********
fi
1
**********
fi
2
**********
fi
1
**********
fi
2

三、分析😈

對於任何須要確保以規範和一致性的方式進行處理Unicode文本的程序來講,規範化都是重要的一部分。尤爲是在處理用戶輸入時接收到的字符串時,此時你沒法控制字符串的編碼方式,那麼規範化文本的表示就顯得更爲重要了。

在對文本進行過濾和淨化時,規範化一樣也佔據了重要的部分。例如,假設想從某些文本中去除全部的音符標記(多是爲了進行搜索或匹配):

import unicodedata
str='啦啦啦\ufb01我是測試\u00f1呱呱呱n\u0303'

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字符
相關文章
相關標籤/搜索