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知道表示数字的符号的数值。

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