【python cookbook】【字符串与文本】9.将Unicode文本统一表示为规范形式

问题:确保所有的Unicode字符串都拥有相同的底层

解决方案:为解决同一个文本拥有多种不同的表示形式问题,应该先将文本统一表示为规范形式,这可以通过unicodedata模块来完成,

unicodedata.normalize(字符串规定采用的规范,字符串)。

在Unicode中,有些特定的字符可以被表示成多种合法的代码点序列。

NFC:表示全组成的字符(即,如果可能的话就使用单个代码点);
NFD:表示组合字符,每个字符应该能完全分解开;
s1 = 'Spicy Jalapeu00f1o'  #Spicy Jalapeño使用的是字符“ñ 的全组成形式(U+00F1)
s2 = 'Spicy Jalapenu0303o' #Spicy Jalapeño使用的是拉丁字母“n”紧跟着一个“~”组合而成的字符(U+0303)

# (a) Print them out (usually looks identical)
print(s1)
print(s2)

# (b) Examine equality and length
print('s1 == s2 ?', s1 == s2)
print('len(s1)=',len(s1), 'len(s1)=',len(s2))
print ('---------------------------')
# (c) Normalize and try the same experiment
import unicodedata

n_s1 = unicodedata.normalize('NFC', s1)
n_s2 = unicodedata.normalize('NFC', s2)

print('n_s1 == n_s2 ?', n_s1 == n_s2)
print('len(n_s1)=',len(n_s1), 'len(n_s2)',len(n_s2))
print ('*****************************')
# (d) Example of normalizing to a decomposed form and stripping accents
t1 = unicodedata.normalize('NFD', s1)
t2 = unicodedata.normalize('NFD', s2)
print ('t1 == t2 ?',t1==t2)
print ('len(t1)=',len(t1),'len(t2)=',len(t2))
print(''.join(c for c in t1 if not unicodedata.combining(c)))
>>> ================================ RESTART ================================
>>> 
Spicy Jalapeño
Spicy Jalapeño
s1 == s2 ? False
len(s1)= 14 len(s1)= 15
---------------------------
n_s1 == n_s2 ? True
len(n_s1)= 14 len(n_s2) 14
*****************************
t1 == t2 ? True
len(t1)= 15 len(t2)= 15
Spicy Jalapeno
>>> 

补充:

在对文本进行过滤和净化时,规范化同样也占据了重要的部分。假设想从某些文本中去除所有的音符标记(可能为了搜索或匹配):

t1 = unicodedata.normalize('NFD', s1)
print(''.join(c for c in t1 if not unicodedata.combining(c)))

unicodedata.combining()对字符做检查,判断它是否文一个组合型字符

这个例子展示了unicodedata模块的另一个重要功能:用来判断字符是否属于某个字符类型;
原文地址:https://www.cnblogs.com/apple2016/p/5791221.html