删除字符中的重音符号,同时保留其他变音符号

时间:2016-03-11 13:58:15

标签: python unicode internationalization nlp cyrillic

在拉丁语和西里尔语中使用的一些斯拉夫语言中,上升和下降的重音符号仅用于上下文中的消歧,即不一致,仅用于元音。

我想要一个Python代码或lib删除元音的尖锐和严重的重音,同时保留其他变音符。

例如:
    жѝзнеспособный - >的жизнеспособный
    сèсефаќа - > сесефаќа
    kȕćica - >的kućica

如果有任何帮助,这里是斯拉夫语言的西里尔字母中所有实际(即非重音)字母的完整列表,包括那些带有变音符号的字母:

абвгдежзиклмнпорстуфхцшєґіїёыіўщъьюяйјњљџђћз́с́ќѓѕ

注意:

  1. їёыіўй是元音,即使在剥离严重和严重的重音标记时也应保持其变音符号。但这是非常罕见的或者可能是不可能的,我们可以忽略这种情况。

  2. зсќѓ是辅音,如拉丁语ćǵśź。他们应该保留他们的强烈重音标记 - 他们不会为发音或消除歧义添加任何标记。

  3. 在精确的正式映射是正式的字母表中,具有尖锐口音的拉丁语辅音的西里尔字母不一定具有强烈的重音。 (也许这很有帮助。)

  4. 双重急性和双重坟墓是低优先级。

  5. 这些人物的背景阅读:
        https://en.wikipedia.org/wiki/I_with_grave_(Cyrillic)#East_Slavic_languages     https://en.wikipedia.org/wiki/Shtokavian#Accentuation
        https://en.wikipedia.org/wiki/Pitch_accent#Serbo-Croatian
        https://en.wikipedia.org/wiki/Bulgarian_alphabet#.D0.8D
        https://en.wikipedia.org/wiki/Macedonian_alphabet#Accented_letters

    类似的问题:
        Removing accents/diacritics from string while preserving other special chars (tried mb_chars.normalize and iconv)
        How to remove accent in Python 3.5 and get a string with unicodedata or other solutions?

2 个答案:

答案 0 :(得分:2)

如果您可以列出相应的对,则不需要库。

>>> unaccentify = {
...    'ѝ': 'и',
...    'о́': 'о'
... }

我打算为此建议string.translate,但遗憾的是它不起作用,因为о́没有单一的代码点。因此,我们确保左手字符是NFKC标准化的:

>>> import unicodedata
>>> unaccentify = {unicodedata.normalize('NFKC', i):j for i, j in unaccentify.items()}

然后我们制作所有可能替换字母的正则表达式:

>>> import re
>>> pattern = re.compile('|'.join(unaccentify))

然后使用pattern.sub进行替换,查看表中的非重音字符。但首先我们需要规范化源字符串:

>>> def replacer(match):
...     return unaccentify[match.group(0)]
...
>>> source = unicodedata.normalize('NFKC', 'жѝзнеспосо́бный')
>>> pattern.sub(replacer, source)
'жизнеспособный'

答案 1 :(得分:0)

这是从上一个答案中获得灵感的(映射字典是兼容的),但使其更加完整且没有正则表达式:

import unicodedata

ACCENT_MAPPING = {
    '́': '',
    '̀': '',
    'а́': 'а',
    'а̀': 'а',
    'е́': 'е',
    'ѐ': 'е',
    'и́': 'и',
    'ѝ': 'и',
    'о́': 'о',
    'о̀': 'о',
    'у́': 'у',
    'у̀': 'у',
    'ы́': 'ы',
    'ы̀': 'ы',
    'э́': 'э',
    'э̀': 'э',
    'ю́': 'ю',
    '̀ю': 'ю',
    'я́́': 'я',
    'я̀': 'я',
}
ACCENT_MAPPING = {unicodedata.normalize('NFKC', i): j for i, j in ACCENT_MAPPING.items()}


def unaccentify(s):
    source = unicodedata.normalize('NFKC', s)
    for old, new in ACCENT_MAPPING.items():
        source = source.replace(old, new)
    return source

请注意,此处的速度无关紧要。

我还没有检查所有字符。如果发现异常,将更新答案。