python - 한국어 - 한글 코드 변환




파이썬 유니 코드 문자열에서 액센트를 제거하는 가장 좋은 방법은 무엇입니까? (6)

나는 파이썬에서 유니 코드 문자열을 가지고 있으며 모든 악센트 (발음 구별 기호)를 제거하고 싶습니다.

필자는 Java에서이 작업을 수행하는 우아한 방법을 웹에서 발견했습니다.

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

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

중요 사항 : 악센트 부호가있는 문자부터 액센트가없는 문자까지 명시 적으로 매핑하는 코드는 피하고 싶습니다.


@ MiniQuark의 대답에 대한 응답으로 :

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

몬트리올, 12.89, 메르, Françoise, noël, 889

필자는 @Jabba의 주석을 통합 할뿐만 아니라 Python 티켓에서 찾은 2 줄과 3 줄을 포함시켜야했습니다.

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 사용)


방금 웹에서이 대답을 발견했습니다.

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)

이것은 악센트뿐만 아니라 "뇌졸중"(ø 등)을 처리합니다.

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(unicode(char))
    cutoff = desc.find(' WITH ')
    if cutoff != -1:
        desc = desc[:cutoff]
    return ud.lookup(desc)

이것이 제가 생각할 수있는 가장 우아한 방식입니다. (그리고이 페이지에 대한 의견으로 알렉시스에 의해 언급되었습니다.) 비록 그것이 실제로 매우 우아하다고는 생각하지 않지만.

유니 코드 이름에는 'WITH'가 없으므로 뒤집힌 문자와 같이 특수 문자가 처리됩니다. 그것은 당신이 어쨌든하고 싶은 것에 달려 있습니다. 때로 사전 정렬 순서를 달성하기 위해 악센트 스트립 핑이 필요했습니다.


이것은 어떤가요:

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_Mark 약자로, MiniQuark의 답변에서 unicodedata.combining과 유사합니다 (unicodedata.combining은 생각하지 않았지만보다 명확한 해결책이므로 더 나은 해결책 일 수 있습니다).

그리고 이러한 조작은 텍스트의 의미를 크게 변경시킬 수 있음을 명심하십시오. 악센트, 움 오토 등은 "장식"이 아닙니다.


Unidecode 에 대한 정확한 대답은 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'

gensim.utils.deaccent(text) - 사람을위한 주제 모델링 :

deaccent("Šéf chomutovských komunistů dostal poštou bílý prášek") 'Sef chomutovskych komunistu dostal postou bily prasek'

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

아니 unicodedata 와 함께 제안 된 솔루션은 일반적으로 일부 문자에서만 악센트를 제거합니다 (예 : 그것은 'ł''' 대신 '' , 'ł' 로 바뀝니다).





diacritics