Gdzie jest „najlepszy ASCII dla tej bazy danych Unicode” w Pythonie?


85

Mam trochę tekstu, który używa interpunkcji Unicode, jak lewy podwójny cudzysłów, prawy pojedynczy cudzysłów jako apostrof i tak dalej, i potrzebuję go w ASCII. Czy Python ma bazę danych tych znaków z oczywistymi substytutami ASCII, więc mogę zrobić coś lepszego niż zamienianie ich wszystkich na "?" ?


21
Jesteś odważnym wojownikiem. Unicode to arcynemezis Pythona.
David Berger

Odpowiedzi:


89

Unidecode wygląda na kompletne rozwiązanie. Konwertuje fantazyjne cytaty na cudzysłowy ascii, akcentowane znaki łacińskie na bez akcentów, a nawet próbuje transliteracji radzić sobie ze znakami, które nie mają odpowiedników ASCII. W ten sposób Twoi użytkownicy nie muszą widzieć wielu? kiedy trzeba było przekazać ich tekst przez starszy 7-bitowy system ascii.

>>> from unidecode import unidecode
>>> print unidecode(u"\u5317\u4EB0")
Bei Jing 

http://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/


3
Hm ... niemieckie umlauty są konwertowane na swój podstawowy charakter zamiast np. Ö = oe, ä = ae itp.
ThiefMaster

4
@ThiefMaster czy te odpowiedniki są prawdziwe we wszystkich językach? Może Unidecode wybiera najniższy wspólny mianownik.
Mark Ransom

Unidecode z pewnością wybiera rozwiązanie niezależne od języka. W przypadku rozwiązania zorientowanego na język niemiecki należy przekonwertować odpowiednie znaki ręcznie ( s/ö/oe/itp.) Przed wyczyszczeniem pozostałych za pomocą unidecode.
Alexis

4
Rzeczywiście, w fińskim na przykład, podczas gdy ä -> a, ö -> ojest wręcz źle, to jest jeszcze korzystniejsze aeioe
Antti Haapala

25

W mojej pierwotnej odpowiedzi również zasugerowałem unicodedata.normalize. Jednak postanowiłem to przetestować i okazuje się, że nie działa w cudzysłowie Unicode. Wykonuje dobrą robotę tłumacząc akcentowane znaki Unicode, więc domyślam się, że unicodedata.normalizejest zaimplementowana za pomocą unicode.decompositionfunkcji, co prowadzi mnie do przekonania, że ​​prawdopodobnie obsługuje tylko znaki Unicode, które są kombinacją litery i znaku diakrytycznego, ale tak naprawdę nie jestem ekspert od specyfikacji Unicode, więc mógłbym po prostu być pełen gorącego powietrza ...

W każdym razie możesz użyć unicode.translatezamiast tego do czynienia ze znakami interpunkcyjnymi. translateMetoda bierze słownika porządkowych Unicode porządkowych Unicode, dzięki czemu można stworzyć mapowanie, które przekłada Unicode tylko interpunkcyjnych ASCII kompatybilny interpunkcji:

'Maps left and right single and double quotation marks'
'into ASCII single and double quotation marks'
>>> punctuation = { 0x2018:0x27, 0x2019:0x27, 0x201C:0x22, 0x201D:0x22 }
>>> teststring = u'\u201Chello, world!\u201D'
>>> teststring.translate(punctuation).encode('ascii', 'ignore')
'"hello, world!"'

W razie potrzeby możesz dodać więcej mapowań interpunkcyjnych, ale nie sądzę, że musisz koniecznie martwić się obsługą każdego pojedynczego znaku interpunkcyjnego Unicode. Jeśli nie trzeba akcentami uchwyt i innych znaków diakrytycznych, nadal można używać unicodedata.normalizedo czynienia z tymi postaciami.



Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.