Unicode文本排序和Unicode數據庫

Python比較任何類型的序列時,會一一比較序列裏的各個元素。

字符串來說,比較的是碼位

對於非ASCII字符比較時, 非ASCII文本的標準排序方式是使用locale.strxfrm函數

使用locale.strxfrm函數之前,必須先爲應用設定合適的區域設置

>>> import locale 
>>> locale.setlocale(locale.LC_COLLATE, 'pt_BR.UTF-8') 
'pt_BR.UTF-8' 
>>> fruits = ['caju', 'atemoia', 'cajá', 'açaí', 'acerola'] 
>>> sorted_fruits = sorted(fruits, key=locale.strxfrm) 
>>> sorted_fruits 
['açaí', 'acerola', 'atemoia', 'cajá', 'caju']

其中有幾點要注意

  • 區域設置是全局的,因此不推薦在庫中調用setlocale函數
  • 操作系統必須支持區域設置,否則setlocale函數會拋出locale.Error: unsupported locale setting異常。
  • 必須知道如何拼寫區域名稱。
  • 操作系統的製作者必須正確實現了所設的區域。

使用Unicode排序算法排序

James Tauber 開發了PyUCA庫,這是Unicode排序算法(Unicode Collation Algorithm,UCA)的純Python實現。

#使用pyuca.Collator.sort_key方法
>>> import pyuca 
>>> coll = pyuca.Collator() 
>>> fruits = ['caju', 'atemoia', 'cajá', 'açaí', 'acerola'] 
>>> sorted_fruits = sorted(fruits, key=coll.sort_key) 
>>> sorted_fruits 
['açaí', 'acerola', 'atemoia', 'cajá', 'caju']

Unicode數據庫

Unicode標準提供了一個完整的數據庫(許多格式化的文本文件),不僅包括碼位與字符
名稱之間的映射,還有各個字符的元數據,以及字符之間的關係。

unicodedata模塊中有幾個函數用於獲取字符的元數據。

#Unicode數據庫中數值字符的元數據示例(各個標號說明輸出中的各列)
import unicodedata 
import re 
 
re_digit = re.compile(r'\d') 
 
sample = '1\xbc\xb2\u0969\u136b\u216b\u2466\u2480\u3285' 
 
for char in sample: 
    print('U+%04x' % ord(char),                        ➊ 
          char.center(6),'re_dig' if re_digit.match(char) else '-','isdig' if char.isdigit() else '-','isnum' if char.isnumeric() else '-',format(unicodedata.numeric(char), '5.2f'),   ➏ 
          unicodedata.name(char),                      ➐ 
          sep='\t')

➊ U+0000格式的碼位。
➋ 在長度爲6的字符串中居中顯示字符。
➌ 如果字符匹配正則表達式r’\d’,顯示re_dig。
➍ 如果char.isdigit()返回True,顯示isdig。
➎ 如果char.isnumeric()返回True,顯示isnum。
➏ 使用長度爲5、小數點後保留2位的浮點數顯示數值。
➐ Unicode標準中字符的名稱。

輸出

U+0031	  1   	re_dig	isdig	isnum	 1.00	DIGIT ONE
U+00bc	  ¼   	-	-	isnum	 0.25	VULGAR FRACTION ONE QUARTER
U+00b2	  ²   	-	isdig	isnum	 2.00	SUPERSCRIPT TWO
U+0969	  ३   	re_dig	isdig	isnum	 3.00	DEVANAGARI DIGIT THREE
U+136b-	isdig	isnum	 3.00	ETHIOPIC DIGIT THREE
U+216b-	-	isnum	12.00	ROMAN NUMERAL TWELVE
U+2466-	isdig	isnum	 7.00	CIRCLED DIGIT SEVEN
U+2480-	-	isnum	13.00	PARENTHESIZED NUMBER THIRTEEN
U+3285-	-	isnum	 6.00	CIRCLED IDEOGRAPH SIX=

分析:第6列是在字符上調用unicodedata.numeric(char)函數得到的結果。這表明,Unicode知道表示數字的符號的數值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章