What is the best way to remove accents in a Python unicode string?

I have a Unicode string in Python, and I would like to remove all the accents (diacritics).

I found on the Web an elegant way to do this in Java:

  • convert the Unicode string to its long normalized form (with a separate character for letters and diacritics)
  • remove all the characters whose Unicode type is "diacritic".
  • Do I need to install a library such as pyICU or is this possible with just the python standard library? And what about python 3?

    Important note: I would like to avoid code with an explicit mapping from accented characters to their non-accented counterpart.


    Unidecode is the correct answer for this. It transliterates any unicode string into the closest possible representation in ascii text.

    Example:

    accented_string = u'Málaga'
    # accented_string is of type 'unicode'
    import unidecode
    unaccented_string = unidecode.unidecode(accented_string)
    # unaccented_string contains 'Malaga'and is of type 'str'
    

    How about this:

    import unicodedata
    def strip_accents(s):
       return ''.join(c for c in unicodedata.normalize('NFD', s)
                      if unicodedata.category(c) != 'Mn')
    

    This works on greek letters, too:

    >>> strip_accents(u"A u00c0 u0394 u038E")
    u'A A u0394 u03a5'
    >>> 
    

    The character category "Mn" stands for Nonspacing_Mark , which is similar to unicodedata.combining in MiniQuark's answer (I didn't think of unicodedata.combining, but it is probably the better solution, because it's more explicit).

    And keep in mind, these manipulations may significantly alter the meaning of the text. Accents, Umlauts etc. are not "decoration".


    I just found this answer on the Web:

    import unicodedata
    
    def remove_accents(input_str):
        nfkd_form = unicodedata.normalize('NFKD', input_str)
        only_ascii = nfkd_form.encode('ASCII', 'ignore')
        return only_ascii
    

    It works fine (for French, for example), but I think the second step (removing the accents) could be handled better than dropping the non-ASCII characters, because this will fail for some languages (Greek, for example). The best solution would probably be to explicitly remove the unicode characters that are tagged as being diacritics.

    Edit : this does the trick:

    import unicodedata
    
    def remove_accents(input_str):
        nfkd_form = unicodedata.normalize('NFKD', input_str)
        return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])
    

    unicodedata.combining(c) will return true if the character c can be combined with the preceding character, that is mainly if it's a diacritic.

    Edit 2 : remove_accents expects a unicode string, not a byte string. If you have a byte string, then you must decode it into a unicode string like this:

    encoding = "utf-8" # or iso-8859-15, or cp1252, or whatever encoding you use
    byte_string = b"café"  # or simply "café" before python 3.
    unicode_string = byte_string.decode(encoding)
    
    链接地址: http://www.djcxy.com/p/9400.html

    上一篇: 从该函数中确定函数名称(不使用追溯)

    下一篇: 删除Python unicode字符串中的重音符号的最佳方法是什么?