我使用以下代码
import unicodedata
def strip_accents(s):
return ''.join(c for c in unicodedata.normalize('NFD', s)
if unicodedata.category(c) != 'Mn')
strip_accents('ewaláièÜÖ')
返回
'ewalaieUO'
但我希望它返回
'ewalaieÜÖ'
有没有比用str.replace(char_a,char_b)替换字符更简单的方法? 我怎样才能有效地处理这个问题?
答案 0 :(得分:2)
那么让我们从你的测试输入开始:
In [1]: test
Out[1]: 'ewaláièÜÖ'
在规范化时看看它发生了什么:
In [2]: [x for x in unicodedata.normalize('NFD', test)]
Out[2]: ['e', 'w', 'a', 'l', 'a', '́', 'i', 'e', '̀', 'U', '̈', 'O', '̈']
以下是每个规范化元素的unicodedata类别:
In [3]: [unicodedata.category(x) for x in unicodedata.normalize('NFD', test)]
Out[3]: ['Ll', 'Ll', 'Ll', 'Ll', 'Ll', 'Mn', 'Ll', 'Ll', 'Mn', 'Lu', 'Mn', 'Lu', 'Mn']
正如你所看到的,不仅“口音”,而且“变音符号”属于Mn
类。因此,您可以使用的是unicodedata.category
unicodedata.name
In [4]: [unicodedata.name(x) for x in unicodedata.normalize('NFD', test)]
Out[4]: ['LATIN SMALL LETTER E',
'LATIN SMALL LETTER W',
'LATIN SMALL LETTER A',
'LATIN SMALL LETTER L',
'LATIN SMALL LETTER A',
'COMBINING ACUTE ACCENT',
'LATIN SMALL LETTER I',
'LATIN SMALL LETTER E',
'COMBINING GRAVE ACCENT',
'LATIN CAPITAL LETTER U',
'COMBINING DIAERESIS',
'LATIN CAPITAL LETTER O',
'COMBINING DIAERESIS']
此处重音名称为COMBINING ACUTE/GRAVE ACCENT
,“变音符号”名称为COMBINING DIAERESIS
。所以这是我的建议,如何修复你的代码:
def strip_accents(s):
return ''.join(c for c in unicodedata.normalize('NFD', s)
if not unicodedata.name(c).endswith('ACCENT'))
strip_accents(test)
'ewalaieÜÖ'
另外,您可以从unicodedata documentation读取此模块只是可用数据库here的包装器,因此请查看该数据库中的list of names以确保涵盖所有案例你需要。