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

StackOverflow https://stackoverflow.com/questions/517923

문제

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

나는 웹에서 Java에서 이것을 할 수있는 우아한 방법을 찾았습니다.

  1. 유니 코드 문자열을 긴 정규화 된 형태로 변환하십시오 (문자와 디아크리닉에 대한 별도의 문자 포함)
  2. 유니 코드 유형이 "diacritic"인 모든 문자를 제거하십시오.

Pyicu와 같은 라이브러리를 설치해야합니까? 아니면 Python 표준 라이브러리만으로 가능합니까? 그리고 Python 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_Mark, Miniquark의 답변에서 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 문자를 삭제하는 것보다 더 잘 처리 될 수 있다고 생각합니다. 최상의 솔루션은 아마도 Diacritics로 태그 된 유니 코드 문자를 명시 적으로 제거하는 것입니다.

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

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 이전 캐릭터와 결합 할 수 있습니다.

편집 2: remove_accents 예상 a 유니 코드 바이트 문자열이 아닌 문자열. 바이트 스트링이있는 경우 다음과 같은 유니 코드 문자열로 디코딩해야합니다.

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)

실제로 프로젝트 호환 Python 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(unicode(char))
    cutoff = desc.find(' WITH ')
    if cutoff != -1:
        desc = desc[:cutoff]
    return ud.lookup(desc)

이것은 내가 생각할 수있는 가장 우아한 방법입니다 (그리고 Alexis 가이 페이지에 대한 의견에서 언급했습니다).

유니 코드 이름에는 'with'가 포함되어 있지 않기 때문에, 회전 및 거꾸로 된 문자와 같이 이것에 의해 처리되지 않는 특별한 글자가 여전히 있습니다. 그것은 당신이 어쨌든하고 싶은 일에 달려 있습니다. 나는 때때로 사전 정렬 순서를 달성하기 위해 악센트 스트리핑이 필요했습니다.

@Miniquark의 답변에 응답하여 :

나는 반 프랑스 (악센트 포함) 인 CSV 파일과 결국 정수와 부유물이 될 줄을 읽으려고 노력했다. 시험으로, 나는 a를 만들었다 test.txt 다음과 같이 보이는 파일 :

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

나는 줄을 포함시켜야했다 2 그리고 3 작업을 수행하려면 (파이썬 티켓에서 찾은) @jabba의 의견을 통합합니다.

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- 인간을위한 주제 모델링:

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

또 다른 해결책은 Unidecode.

제안 된 솔루션이 아닙니다 유니 코드데다 일반적으로 일부 캐릭터에서만 악센트를 제거합니다 (예 : 회전합니다. 'ł' ~ 안으로 '', 'l').

일부 언어는 언어 문자와 악센트 디아크리닉으로 디아크리닉을 결합하여 악센트를 지정합니다.

스트라이프하려는 이성화를 명시 적으로 지정하는 것이 더 안전하다고 생각합니다.

def strip_accents(string, accents=('COMBINING ACUTE ACCENT', 'COMBINING GRAVE ACCENT', 'COMBINING TILDE')):
    accents = set(map(unicodedata.lookup, accents))
    chars = [c for c in unicodedata.normalize('NFD', string) if c not in accents]
    return unicodedata.normalize('NFC', ''.join(chars))
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top