标签:
问题:确保所有的Unicode字符串都拥有相同的底层
解决方案:为解决同一个文本拥有多种不同的表示形式问题,应该先将文本统一表示为规范形式,这可以通过unicodedata模块来完成,
unicodedata.normalize(字符串规定采用的规范,字符串)。
在Unicode中,有些特定的字符可以被表示成多种合法的代码点序列。
NFC:表示全组成的字符(即,如果可能的话就使用单个代码点);
NFD:表示组合字符,每个字符应该能完全分解开;
s1 = ‘Spicy Jalape\u00f1o‘ #Spicy Jalapeño使用的是字符“ñ” 的全组成形式(U+00F1) s2 = ‘Spicy Jalapen\u0303o‘ #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 Jalapen?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模块的另一个重要功能:用来判断字符是否属于某个字符类型;
【python cookbook】【字符串与文本】9.将Unicode文本统一表示为规范形式
标签:
原文地址:http://www.cnblogs.com/apple2016/p/5791221.html