[python] 파이썬 유니 코드 문자열에서 악센트를 제거하는 가장 좋은 방법은 무엇입니까?

파이썬에는 유니 코드 문자열이 있으며 모든 악센트 (분음 부호)를 제거하고 싶습니다.

웹에서 Java로 이것을 수행하는 우아한 방법을 찾았습니다.

  1. 유니 코드 문자열을 긴 정규화 된 형식으로 변환하십시오 (문자와 분음 부호에 별도의 문자 사용)
  2. 유니 코드 유형이 “분음 부호”인 모든 문자를 제거하십시오.

pyICU와 같은 라이브러리를 설치해야합니까, 아니면 파이썬 표준 라이브러리만으로 가능합니까? 그리고 파이썬 3은 어떻습니까?

중요 사항 : 악센트 문자에서 악센트가 아닌 문자로 명시 적으로 매핑 된 코드를 피하고 싶습니다.



답변

Unidecode 가 이에 대한 정답입니다. 유니 코드 문자열을 ASCII 텍스트에서 가장 가까운 표현으로 음역합니다.

예:

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'


답변

이건 어때요:

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

이것은 그리스 문자에서도 작동합니다.

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

문자 카테고리 “Mn을”의 약자 Nonspacing_MarkMiniQuark의 대답에 unicodedata.combining 유사하다이, (나는 unicodedata.combining 생각하지 않았지만, 좀 더 명시 적으로 있기 때문에 그것은 아마도 더 나은 솔루션입니다).

이러한 조작으로 인해 텍스트의 의미가 크게 변경 될 수 있습니다. 악센트, 움라우트 등은 “장식”이 아닙니다.


답변

방금 웹 에서이 답변을 찾았습니다.

import unicodedata

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

(예를 들어 프랑스어) 잘 작동하지만 비 ASCII 문자를 삭제하는 것보다 두 번째 단계 (액센트 제거)가 더 잘 처리 될 수 있다고 생각합니다. 일부 언어 (예 : 그리스)에서는 실패하기 때문입니다. 가장 좋은 해결책은 아마도 분음 부호로 태그가 지정된 유니 코드 문자를 명시 적으로 제거하는 것입니다.

편집 : 이것은 트릭을 수행합니다.

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)문자 c를 선행 문자와 결합 할 수있는 경우 , 즉 분음 부호 인 경우 true를 리턴합니다 .

편집 2 : remove_accents기대 유니 코드 문자열이 아닌 바이트 문자열입니다. 바이트 문자열이 있으면 다음과 같이 유니 코드 문자열로 디코딩해야합니다.

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)


답변

실제로 나는 프로젝트 호환 파이썬 2.6, 2.7 및 3.4에서 일하고 있으며 무료 사용자 항목에서 ID를 만들어야합니다.

덕분에 놀라운 기능을하는이 기능을 만들었습니다.

import re
import unicodedata

def strip_accents(text):
    """
    Strip accents from input String.

    :param text: The input string.
    :type text: String.

    :returns: The processed String.
    :rtype: String.
    """
    try:
        text = unicode(text, 'utf-8')
    except (TypeError, NameError): # unicode is a default on python 3 
        pass
    text = unicodedata.normalize('NFD', text)
    text = text.encode('ascii', 'ignore')
    text = text.decode("utf-8")
    return str(text)

def text_to_id(text):
    """
    Convert input text to id.

    :param text: The input string.
    :type text: String.

    :returns: The processed String.
    :rtype: String.
    """
    text = strip_accents(text.lower())
    text = re.sub('[ ]+', '_', text)
    text = re.sub('[^0-9a-zA-Z_-]', '', text)
    return text

결과:

text_to_id("Montréal, über, 12.89, Mère, Françoise, noël, 889")
>>> 'montreal_uber_1289_mere_francoise_noel_889'


답변

이것은 악센트뿐만 아니라 “스트로크”(ø 등)도 처리합니다.

import unicodedata as ud

def rmdiacritics(char):
    '''
    Return the base character of char, by "removing" any
    diacritics like accents or curls and strokes and the like.
    '''
    desc = ud.name(char)
    cutoff = desc.find(' WITH ')
    if cutoff != -1:
        desc = desc[:cutoff]
        try:
            char = ud.lookup(desc)
        except KeyError:
            pass  # removing "WITH ..." produced an invalid name
    return char

이것은 내가 생각할 수있는 가장 우아한 방법입니다 (그리고이 페이지의 주석에서 알렉시스에 의해 언급되었습니다). 그러나 그것이 정말로 우아하다고 생각하지는 않습니다. 실제로, 주석에서 지적했듯이 유니 코드 이름은 실제로 이름 일 뿐이므로 일관성 또는 기타 사항을 보장하지 않습니다.

유니 코드 이름에 ‘WITH’가 포함되어 있지 않기 때문에 회전 및 반전 문자와 같이 여전히 처리되지 않는 특수 문자가 있습니다. 어쨌든 당신이하고 싶은 일에 달려 있습니다. 때로는 사전 정렬 순서를 달성하기 위해 악센트 제거가 필요했습니다.

참고 수정 :

주석 (처리 조회 오류, Python-3 코드)의 제안을 통합했습니다.


답변

@MiniQuark 님의 답변에 답변 :

하프 프랑스어 (액센트 포함) 인 csv 파일과 정수 및 부동 소수점이되는 일부 문자열을 읽으려고했습니다. 테스트로 test.txt다음과 같은 파일을 만들었습니다 .

Montréal, über, 12.89, Mère, Françoise, noël, 889

나는 선을 포함했다 23(나는 파이썬 티켓에 있음) 작업에 얻을뿐만 아니라, 자바 더의 코멘트 @ 법인 (法人) :

import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import csv
import unicodedata

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

with open('test.txt') as f:
    read = csv.reader(f)
    for row in read:
        for element in row:
            print remove_accents(element)

결과:

Montreal
uber
12.89
Mere
Francoise
noel
889

(참고 : Mac OS X 10.8.4에서 Python 2.7.3을 사용하고 있습니다)


답변

gensim.utils.deaccent (텍스트) 에서 Gensim – 인간에 대한 주제 모델링 :

'Sef chomutovskych komunistu dostal postou bily prasek'

또 다른 해결책은 unidecode 입니다.

와 제안 된 솔루션을 유의 한편 UnicodeData은 일반적으로 (예를 들어,이 회전 일부 문자에 악센트를 제거 'ł'''대신에보다 'l').