2012-01-19 8 views
8

Poszukuję szybkiego i możliwie wygodnego sposobu w Pythonie 3 do tłumaczenia ciągów z nie-ASCII literami na słowa zawierające tylko litery ASCII.Tłumaczenie liter nie w 7bit ASCII na ASCII (jak ń na n i ą na a)

Przykłady!

Żółw => Żółw

móżdżek => móżdżek

Łódź => Łódź

i tak dalej ...

Istnieje wiele litery alfabetów narodowych, które mogą stać się Litery ASCII (jak od ń do n). Mogę to zrobić ręcznie dla mojego języka (polskiego), określając, jak tłumaczyć każdą literę. Ale czy istnieje zautomatyzowany sposób na zrobienie tego? Albo jakąś bibliotekę, która zrobiłaby to, czego potrzebuję?

Pythons str.encode() nie zrobi, bo "żółw".encode('ascii', 'replace') == "???w" i "żółw".encode('ascii', 'ignore') == "w" ...

mogę zrobić takie tłumaczenie dla polskich liter, ale nie chcę, aby to zrobić na każdym innym języku:

>>> utf8_letters = ['ą','ę','ć','ź','ż','ó','ł','ń','ś'] 
>>> ascii_letters = ['a','e','c','z','z','o','l','n','s'] 
>>> trans_dict = dict(zip(utf8_letters,ascii_letters)) 
>>> turtle = "żółw" 
>>> out = [] 
>>> for l in turtle: 
... out.append(trans_dict[l] if l in trans_dict else l) 
>>> result = ''.join(out) 
>>> result 
'zolw' 

Powyższy kod robi co chcę z polskimi literami, ale jest brzydki: < Jaki jest najlepszy sposób na zrobienie tego?

Oczywiście takie tłumaczenia zmienią znaczenie niektórych słów, ale to jest w porządku.

+1

Należy pamiętać, że w niektórych językach to, co niektóre uznałoby za akcentowaną literę, jest uważane za odrębną literę w tym języku. Na przykład litera "å" w języku szwedzkim jest zwykle uważana za odrębną literę od "a", a nie po prostu literę "a" z pierścieniem nad nią. – dreamlax

+0

Jestem tego świadomy ... Chodzi o to, że kiedy piszę po polsku, gdzie moje listy narodowe nie są obsługiwane, używam tych "tłumaczeń", o których pisałem. Sądzę, że ludzie z innych krajów mają swoje własne sposoby pisania w takich środowiskach. Chciałbym wiedzieć, jak można dokonać takich transformacji. – Maciek

+0

@John Saunders, dzięki, że moja odpowiedź jest całkowicie nieważna. –

Odpowiedz

5

Można do tego celu użyć modułu unicodedata. Posiada funkcje do manipulowania nazwami znaków Unicode: name i lookup.

Teraz spójrzmy na nie bliżej.

name('Ż') == 'LATIN CAPITAL LETTER Z WITH DOT ABOVE' 
name('ł') == 'LATIN SMALL LETTER L WITH STROKE' 
lookup('LATIN CAPITAL LETTER Z') == 'Z' 
lookup('LATIN SMALL LETTER L') == 'l' 

Zobacz wzór? Zróbmy funkcję, która wykorzystuje go:

import unicodedata 

def normalize_char(c): 
    try: 
     cname = unicodedata.name(c) 
     cname = cname[:cname.index(' WITH')] 
     return unicodedata.lookup(cname) 
    except (ValueError, KeyError): 
     return c 

normalize_char('ę') == 'e' 
normalize_char('Ę') == 'E' 
normalize_char('ś') == 's' 

Wygląda na słowo Z w imię postaci, usuwa wszystko, co idzie za nim i karmi go z powrotem do funkcji lookup.
Jeśli nie ma wartości "Z", to podniesiono ValueError, a gdy nie ma znaku o takiej nazwie, podniesiono KeyError, więc funkcja zwraca znak niezmieniony.

I tu jest funkcją, która „tłumaczy” ciąg na podstawie poprzedniej funkcji:

def normalize(s): 
    return ''.join(normalize_char(c) for c in s) 

normalize('Móżdżek') == 'Mozdzek' 

więc to rozwiązanie jest oczywiście bardzo dobra, ale zostawię poprzednich poniżej.


Moduł unicodedata posiada również funkcję, która obiecuje podobne wyniki – normalize z 'NFKD' parametru (rozkład kompatybilność), ale nie zdobywa najwięcej znaków.


Jeśli masz dane postaci, podany kod może zostać poprawiony.

letters={'ł':'l', 'ą':'a', 'ń':'n', 'ć':'c', 'ó':'o', 'ę':'e', 'ś':'s', 'ź':'z', 'ż':'z'} 
trans=str.maketrans(letters) 
result=text.translate(trans) 

Here to ładna tabela z danymi postaci. To jest JavaScript, ale można go łatwo użyć w Pythonie.


A jeśli nie masz nic przeciwko korzystaniu z zewnętrznych bibliotek, możesz wypróbować Unidecode. Został stworzony właśnie na to.

+0

Unefinedat unicodedata.normalize ('NFKD', "żółw") == 'żółw' nie 'zolw' :( – Maciek

+0

A co z rozkładaniem na NFD, a następnie wyrzucaniem wszystkich znaków łączenia? –

+0

Ten stół, który lubiłeś, jest świetny i to Biblioteka Unidecode jest dość obiecująca! Na razie nie ma na to lepszego sposobu: – Maciek

Powiązane problemy