2010-03-07 3 views
2

에서 UTF-8로 HTML ASCII가 아닌 데이터를 인코딩하는 방법 나는 그렇게했는데, 나는이 오류를 발견 : 나는 인쇄 문을 사용하는 경우파이썬

>>> import re 
>>> x = 'Ingl\xeas' 
>>> x 
'Ingl\xeas' 
>>> print x 
Ingl�s 
>>> x.decode('utf8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode 
     return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 4-5: unexpected end of data 
>>> x.decode('utf8', 'ignore') 
u'Ingl' 
>>> x.decode('utf8', 'replace') 
u'Ingl\ufffd' 
>>> print x.decode('utf8', 'replace') 
Ingl� 
>>> print x.decode('utf8', 'xmlcharrefreplace') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode 
     return codecs.utf_8_decode(input, errors, True) 
TypeError: don't know how to handle UnicodeDecodeError in error callback 

가, 내가 원하는을 그 :

>>> print x 
u'Inglês' 

도움이됩니다.

답변

7

입력 된 데이터가 디코딩되기 전에 어떻게 인코딩되는지 알아야합니다. 여러분 중에는 UTF-8에서 해독하려고 시도하고 있지만 입력이 유효한 UTF-8이 아니기 때문에 파이썬에서 예외가 발생합니다. 그것은 마치 라틴 -1 일 것 같습니다. 이 작품은 나를 위해 :

>>> x = 'Ingl\xeas' 
>>> print x.decode('latin1') 
Inglês 

당신은 "비 ASCII HTML"을 언급했다. 웹 서버 스크립트를 작성 중이며 HTTP 요청에서 데이터를 가져 오는 경우 Content-Type 헤더를 확인해야합니다. 이상적인 세계에서는 클라이언트가 데이터를 위해 사용하는 인코딩을 알려줍니다. 클라이언트가 올바르게 작동하지 않을 수 있습니다.

희망 하시겠습니까?

0
Ingl\xeas 

은 UTF-8이 아니지만 Windows-1252 또는 latin1로 인코딩되었을 수 있습니다. 먼저 해독해야합니다. 그런 다음에 만 UTF-8로 인코딩 할 수 있습니다. 따라서

: 마찬가지로

>>> x = 'Ingl\xeas' 
>>> print x.decode("cp1252") 
Inglês 

올바른 UTF-8로 표현이다

>>> x.decode("cp1252").encode("UTF-8") 
'Ingl\xc3\xaas' 

. 파이썬 3 문자열은 항상 (bytes 객체를 계산하지 않음) 유니 코드 문자열이기 때문에 그런데

, 파이썬 3에서, 당신은 (Windows에서 대화 형 콘솔에서 적어도) 단순히

>>> x = 'Ingl\xeas' 
>>> print (x) 
Inglês 

를 입력 할 수 있습니다.

+0

파이썬 3은 파이썬 2와 같이 2 개의 문자열 유형을 가지고 있습니다. 3의'str'은 사소한 수정으로 2의'유니 코드 '입니다. 3의'bytes'는 적당히 수정 된 2의'str'입니다. –

+0

Python 3 예제에서 UnicodeEncodeError 예외가 발생합니다. –

+0

@Daniel : 대화 형 셸에 없습니다. –

0

일부 관찰 :

(1) latin1 예외를 던지는없이 8 비트 바이트를 디코딩 할 것이다. 다른 모든 가능성을 모두 소진 한 경우에만 latin1을 사용하십시오. 특정 파일 또는 웹 페이지 나 XML 스트림으로 인코딩되는 것을 결정하기 위해 chardet를 사용

(2) 가능한 대안 매우 제한된 증거 (한 문자)를 기반으로 :.

>>> import unicodedata as ucd 
>>> for codepage in range(1250, 1259): 
... try: 
...  uc = "\xea".decode(str(codepage)) 
... except UnicodeDecodeError: 
...  pass 
... if uc == u'\xea': print codepage, ucd.name(uc) 
... 
1252 LATIN SMALL LETTER E WITH CIRCUMFLEX 
1254 LATIN SMALL LETTER E WITH CIRCUMFLEX 
1256 LATIN SMALL LETTER E WITH CIRCUMFLEX 
1258 LATIN SMALL LETTER E WITH CIRCUMFLEX 
>>> 

(3) 범위 U +0080 ~ U + 009F (포함)는 "C1 제어 문자"에 할당됩니다.이 제어 문자는 unicode.org 외부에서 아무도 사용할 수 없다는 것을 알고 있습니다. 어떤 인코딩을 사용하든 상관없이 (심지어 UTF-8), 유니 코드에 대한 예외 디코딩이 끝난 후에도, 당신은 아직 숲속에 있지 않습니다. 해당 범위의 문자를 확인하십시오. 무엇이든 찾으면 데이터가 손상되었거나 선택한 인코딩이 올바르지 않습니다.

def check_for_c1_control_characters(unicode_obj): 
    return any('\u0080' <= c <= '\u009F' for c in unicode_obj) 

또는 데이터가 손상 될 수있는 여러 가지 방법 중 하나를 해결하는 방법의 this example에서와 같이 정규식을 사용합니다.