5

Mam tekst, który zawiera znaki takie jak "\ xaf", "\ xbe", które, jak rozumiem z this question, są znakami zakodowanymi w ASCII.Jak przekonwertować zakodowane znaki xXY na UTF-8 w Pythonie?

Chcę przekonwertować je w Pythonie na ich odpowiedniki w formacie UTF-8. Zwykle string.encode("utf-8") rzuca UnicodeDecodeError. Czy jest jakiś lepszy sposób, na przykład, ze standardową biblioteką codecs?

Próbka 200 characters here.

+0

Twoja próbka nie zawiera żadnych '\ xaf' lub jak. Czy masz próbki z takimi postaciami? – dkarp

+0

Twoje przykładowe dane * mają * poprawny kod UTF-8. Z znakami kontrolnymi "separator rekordów" i "separator jednostek". – dan04

+0

Zgodnie z 'enca' (http://linux.die.net/man/1/enca) jest to UTF-8" otoczony/wymieszany z danymi nietekstowymi ". –

Odpowiedz

2

Twój plik jest już zakodowany w UTF-8.

# saved encoding-sample to /tmp/encoding-sample 
import codecs 
fp= codecs.open("/tmp/encoding-sample", "r", "utf8") 
data= fp.read() 

import unicodedata as ud 

chars= sorted(set(data)) 
for char in chars: 
    try: 
     charname= ud.name(char) 
    except ValueError: 
     charname= "<unknown>" 
    sys.stdout.write("char U%04x %s\n" % (ord(char), charname)) 

i ręczne wypełnianie nieznanych nazwach:
char U000a LINE FEED
char U001e INFORMACJE SEPARATOR DWA
char U001f INFORMACJE SEPARATOR ONE

+0

Dzięki, masz rację, krótka próbka, którą podałem jest UTF-8. jednak (niestety) w całym pliku istnieją części zakodowane w różnych innych kodowaniach (głównie windows-1250). Rozwiązałem to przez "spróbuj" do "ciąg".decode() 'dla najbardziej powszechnych kodowań i, jeśli wszystko zawiedzie, zgadywanie kodowania z biblioteką' chardet'. –

2

To nie jest ASCII (kody ASCII idą tylko do 127, \xaf to 175). Najpierw musisz znaleźć poprawne kodowanie, dekodować je, a następnie ponownie kodować w UTF-8.

Czy możesz podać rzeczywistą próbkę ciągu? Wtedy możemy prawdopodobnie odgadnąć aktualne kodowanie.

+0

Edytowałem pytanie, aby dodać link do krótkiej próbki. –

+0

Ten przykład nie wygląda mi na zakodowany tekst, a raczej na zastrzeżony format. –

+0

Powinien być w formacie MARC (http://www.loc.gov/marc/). Kiedy próbowałem wykryć jego kodowanie za pomocą 'enca', otrzymałem odpowiedź, że jest to głównie UTF-8 przeplatany ze znakami innymi niż tekstowe. –

3

.encode dla konwersji unikodowego (unicode w 2.x str w 3.x) Do ciąg bajtów (str w 2.x bytes w 3.x).

W wersji 2.x można wywołać .encode na obiekcie str. Python domyślnie dekoduje ciąg znaków do Unicode: s.encode(e) działa tak, jak gdybyś napisał s.decode(sys.getdefaultencoding()).encode(e).

Problem polega na tym, że domyślne kodowanie to "ascii", a Twój ciąg znaków zawiera znaki spoza zestawu ASCII. Możesz rozwiązać ten problem, jawnie określając poprawne kodowanie.

>>> '\xAF \xBE'.decode('ISO-8859-1').encode('UTF-8') 
'\xc2\xaf \xc2\xbe' 
+0

To dobrze, ale reszta tekstu jest zakodowana jako UTF-8 (przynajmniej to zostało zgłoszone przez 'enca'). Tak więc tej procedury nie można zastosować do całego tekstu. –

+2

Więc znaki \ xXY są w ISO-8859-1? –

Powiązane problemy