我会使用
Unicode标准化来处理这个问题。
像带重音和点之类的字符是
预组合Unicode字符。如果你将它们分解,就可以得到基本字符加上重音、点等
组合字符。然后你就可以删除不需要的部分,重新组合字符串成为预组合字符。
你可以在Python中使用
unicodedata.normalize
来实现。具体来说,你需要使用“NFD”(
规范分解形式)标准化形式。这将给你字符的规范分解形式。然后,要重新组合字符,你需要使用“NFC”(
规范组合形式)。
我将向您展示我的意思。首先,让我们看一下您提供的示例文本中的各个代码点:
>>> from pprint import pprint
>>> import unicodedata
>>> text = 'ọmọàbúròẹlẹ́wà'
>>> pprint([unicodedata.name(c) for c in text])
['LATIN SMALL LETTER O WITH DOT BELOW',
'LATIN SMALL LETTER M',
'LATIN SMALL LETTER O WITH DOT BELOW',
'LATIN SMALL LETTER A WITH GRAVE',
'LATIN SMALL LETTER B',
'LATIN SMALL LETTER U WITH ACUTE',
'LATIN SMALL LETTER R',
'LATIN SMALL LETTER O WITH GRAVE',
'LATIN SMALL LETTER E WITH DOT BELOW',
'LATIN SMALL LETTER L',
'LATIN SMALL LETTER E WITH ACUTE',
'COMBINING DOT BELOW',
'LATIN SMALL LETTER W',
'LATIN SMALL LETTER A WITH GRAVE']
正如您所看到的,其中一个字符已经部分分解(具有单独的“带点下加符号”的字符)。现在让我们来看看完全分解的情况:
>>> text = unicodedata.normalize('NFD', text)
>>> pprint([unicodedata.name(c) for c in text])
['LATIN SMALL LETTER O',
'COMBINING DOT BELOW',
'LATIN SMALL LETTER M',
'LATIN SMALL LETTER O',
'COMBINING DOT BELOW',
'LATIN SMALL LETTER A',
'COMBINING GRAVE ACCENT',
'LATIN SMALL LETTER B',
'LATIN SMALL LETTER U',
'COMBINING ACUTE ACCENT',
'LATIN SMALL LETTER R',
'LATIN SMALL LETTER O',
'COMBINING GRAVE ACCENT',
'LATIN SMALL LETTER E',
'COMBINING DOT BELOW',
'LATIN SMALL LETTER L',
'LATIN SMALL LETTER E',
'COMBINING DOT BELOW',
'COMBINING ACUTE ACCENT',
'LATIN SMALL LETTER W',
'LATIN SMALL LETTER A',
'COMBINING GRAVE ACCENT']
现在根据您的要求,看起来您想保留所有拉丁字母(可能还有ASCII的其他字符,我猜测),以及“COMBINING DOT BELOW”代码点,我们可以使用文字'\N{COMBINING DOT BELOW}'来引用它,使您的代码更易读。
这是一个示例函数,我认为它会实现您想要的功能:
import unicodedata
def remove_accents_but_not_dots(input_text):
decomposed_text = unicodedata.normalize('NFD', input_text)
filtered_text = ''
for c in decomposed_text:
if ord(c) <= 0x7f or c == '\N{COMBINING DOT BELOW}':
filtered_text += c
return unicodedata.normalize('NFC', filtered_text)
当然,在Python中字符串连接速度较慢,但我会将优化留给您。这个例子是为了可读性而编写的。
以下是结果的样子:
>>> remove_accents_but_not_dots('ọmọàbúròẹlẹ́wà')
'ọmọaburoẹlẹwa'