파이썬 유니 코드 문자열에서 액센트를 제거하는 가장 좋은 방법은 무엇입니까?
-
21-08-2019 - |
문제
파이썬에는 유니 코드 문자열이 있으며 모든 액센트 (Diacritics)를 제거하고 싶습니다.
나는 웹에서 Java에서 이것을 할 수있는 우아한 방법을 찾았습니다.
- 유니 코드 문자열을 긴 정규화 된 형태로 변환하십시오 (문자와 디아크리닉에 대한 별도의 문자 포함)
- 유니 코드 유형이 "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))