2008-11-06 4 views
15

필자는 파이썬에서 헤더 필드에 이상한 바이트가 발생하는 메일 처리 소프트웨어를 작성하고 있습니다. 이 메일이 잘못된 것 같습니다. 메시지 자체는 us-ascii라고 주장하기 때문에 실제 인코딩은 없다고 생각하지만, UnicodeDecodeError을 던지지 않고 원래의 코드를 근사하는 유니 코드 문자열을 얻고 싶습니다.일부 바이트의 문자 인코딩을 추측하려고하는 Python 라이브러리 함수가 있습니까?

그래서, 나는 str과 선택적으로 힌트를 취하고, 그에게 가장 가까운 것을 unicode으로 돌려주는 함수를 찾고있다. 물론 그 중 하나를 쓸 수는 있지만 그러한 기능이 존재한다면 저자는 아마 이것에 관해 가장 좋은 방법에 대해 조금 더 깊이 생각했을 것입니다.

파이썬의 디자인은 암시 적으로 표현하기를 좋아하며 표준 라이브러리는 텍스트 디코딩시 암시적인 마술을 피하도록 설계된 것으로 알고 있습니다. 나는 단지 명시 적으로 "앞서 가서 추측하다"라고 말하고 싶습니다.

답변

12

내가 알 수있는 한, 표준 라이브러리는 기능을 가지고 있지 않지만 위에 제시된대로 작성하는 것이 어렵지 않습니다. 문자열을 디코드하고 예외를 throw하지 않을 것이라고 보장하는 방법을 찾고 있다고 생각했습니다. string.decode의 errors 매개 변수는이를 수행합니다.

def decode(s, encodings=('ascii', 'utf8', 'latin1')): 
    for encoding in encodings: 
     try: 
      return s.decode(encoding) 
     except UnicodeDecodeError: 
      pass 
    return s.decode('ascii', 'ignore') 
+1

끝에 'ascii'' case를 건너 뛰고'latin1'을 사용하면됩니다. 왜냐하면'latin1'은 에러없이 모든 256 바이트 값을 디코딩 할 것이기 때문입니다. –

20

Universal Encoding Detector에 관심이있을 수 있습니다.

+0

+1보다 5 초 빠릅니다 :-) –

+0

정말 감사합니다. 표준 라이브러리에는 없습니다. – Nick

18

+1 chardet 모듈의 경우 (@insin으로 제안)

그것은 표준 라이브러리에없는,하지만 당신은 쉽게 다음과 같은 명령으로 설치할 수 있습니다

$ pip install chardet 

Example : 당신이없는 경우

>>> import chardet 
>>> import urllib 
>>> detect = lambda url: chardet.detect(urllib.urlopen(url).read()) 
>>> detect('http://stackoverflow.com') 
{'confidence': 0.85663169917190185, 'encoding': 'ISO-8859-2'}  
>>> detect('https://stackoverflow.com/questions/269060/is-there-a-python-lib') 
{'confidence': 0.98999999999999999, 'encoding': 'utf-8'} 

Installing Pip를 참조하십시오.

+1

'ISO-8859-2'는 말도 안 되니? –

+0

@ John Machin : 그렇습니다. 그것은 당신이 그것을 맹목적으로 신뢰해서는 안된다는 것을 보여주는 교육입니다. 현재 결과는 다릅니다 (이에 상응하여 'utf-8'및 'ascii'). – jfs

1

내가 찾은 최선의 방법은 try except 블록 내부에서 가장 일반적인 인코딩을 각각 사용하여 잠재 고객을 반복적으로 해독하는 것입니다.