>  기사  >  백엔드 개발  >  파이썬 블랙 매직 인코딩 변환 방법

파이썬 블랙 매직 인코딩 변환 방법

高洛峰
高洛峰원래의
2017-03-13 18:15:331116검색

이 글은 python 블랙마법의 인코딩 변환을 주로 소개하고, 파이썬 인코딩 변환 방법을 분석합니다. 관심 있는 친구들은

라이브러리에서 인코딩을 할 때 다른 언어를 사용하고 있음을 참고하세요. 변환 시, 일반적으로 이해할 수 없는 문자를 처리하는 방법은 두 가지(또는 세 가지)뿐입니다:

  • 예외 발생

  • 은 대체 문자

  • 건너뛰기 로 대체됩니다.

그러나 복잡한 현실 세계에서는 다양한 불안정성으로 인해 우리가 처리하는 텍스트에는 혼합 인코딩과 같은 불일치 요소가 항상 존재합니다. 이 경우에는 위의 접근 방식으로 돌아갑니다.

그렇다면 파이썬에 더 좋은 방법이 있을까요?

답은 그렇습니다!

Python의 인코딩 변환 프로세스는 실제로 2단계 변환입니다.


source -> unicode -> dest

먼저 문자열을 원래 인코딩에서 유니코드로 변환합니다. . 그런 다음 유니코드를 대상 인코딩으로 변환합니다.

첫 번째 단계에서는 일반적으로 decode() 또는 unicode()이 두 가지 기능 완료되었습니다. 두 번째 단계에서는
encode() 함수를 사용하여 완료합니다.

여기서 말하는 흑마술은 첫 번째 단계에서 실현됩니다.

decode 및 unicode 함수에는 모두

errors라는 선택적 매개변수가 있습니다. 공식 설명을 살펴보세요:

  • 다른 오류를 설정하기 위해 오류가 제공될 수 있습니다

  • 처리 방식. 기본값은 '엄격'입니다. 즉, 인코딩 오류가 발생합니다.

  • UnicodeDecodeError. 다른 가능한 값은 'ignore' 및 'replace'

  • 입니다.

  • UnicodeDecodeError를 처리할 수 있는
    코덱에 등록된 이름입니다. 🎜>

  • 이 매개변수에는 일반적으로

  • 엄격한 기본값이라는 세 가지 값이 있습니다. 인코딩 오류가 발생하면 UnicodeDecodeError가 발생합니다.

  • 건너뛰기를 무시합니다.

  • 바꾸다 ?

  • 자, 마지막 문장 보셨나요? 쇼가 시작되었습니다!

모듈 코덱에는 Register_error라는 함수가 있습니다. 이 기능을 통해 사용자는 사용자 정의 오류 처리 방법을 등록할 수 있습니다.

UnicodeDecodeError를 처리하는 데 사용됩니다.


함수 프로토타입을 살펴보겠습니다.

codecs.register_error(name, error_handler)

name:

오류 처리기의 이름

. 디코드 기능의 오류 매개변수를 채우는 데 사용됩니다. error_handler: 처리 기능. 이 함수는 예외 매개변수를 허용합니다. 튜플을 반환합니다. 튜플에는 2개의 요소가 있습니다. 첫 번째는 오류가 수정된 문자열이고 두 번째는 디코딩을 계속할 시작 위치입니다. 구체적인 구현을 살펴보겠습니다.

def cjk_error(e):
  if not isinstance(e, UnicodeDecodeError):
    raise TypeError("don't know how to handle %r" % exc) 
  if exc.end + 1 > len(exc.object): 
    raise TypeError('unknown codec ,the object too short!') 
  ch1 = ord(exc.object[exc.start:exc.end]) 
  newpos = exc.end + 1 
  ch2 = ord(exc.object[exc.start + 1:newpos]) 
  sk = exc.object[exc.start:newpos] 
  if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK 
    return (unicode(sk,&#39;cp936&#39;), newpos) 
  if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5 
    return (unicode(sk,&#39;big5&#39;), newpos) 
  raise TypeError(&#39;unknown codec !&#39;) 
codecs.register_error("cjk_replace", cjk_replace)

위 내용은 제가 인터넷에서

복사
한 것입니다. 처음에는 아주 좋다고 생각했는데, 나중에 보니 매우 반영성이 없는 알고리즘이라는 것을 알게 되었습니다.

예를 들어 utf8과 gbk는 처음 2바이트에 교차점이 있습니다. utf8 문자열을 gbk 인코딩으로 디코딩하면 세 번째 바이트부터 오류가 발생합니다(처음 2바이트는 gbk 인코딩 범위의 한자에 해당할 수도 있음).

예:

a = "你"              # utf8编码:&#39;\xe4\xbd\xa0&#39;
c = unicode(a[:2],&#39;gbk&#39;)  # 正常返回
c = unicode(a, &#39;gbk&#39;)    # UnicodeDecodeError 。错误发生在第三个字节

이러한 상황을 위해 다음과 같이 개선했습니다.


import codec

def cjk_replace(e):
  if not isinstance(e, UnicodeDecodeError):
    raise TypeError("invalid exception type %s" e)

  src = e.encoding
  if src in (&#39;gbk&#39;,&#39;gb18030&#39;, &#39;big5&#39;):
    beg = e.start - 2
    if beg >= 0:
      try:
        return unicode(e.object[beg:e.end], &#39;utf8&#39;), e.end + 1
      except:
        pass

  if exc.end + 1 > len(exc.object):
    raise TypeError(&#39;unknown codec ,the object too short!&#39;)
  ch1 = ord(exc.object[exc.start:exc.end])
  newpos = exc.end + 1
  ch2 = ord(exc.object[exc.start + 1:newpos])
  sk = exc.object[exc.start:newpos]

  if src != &#39;gbk&#39; and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK
    return (unicode(sk,&#39;cp936&#39;), newpos)
  if src != &#39;big5&#39; and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5
    return (unicode(sk,&#39;big5&#39;), newpos)
  raise TypeError(&#39;unknown codec !&#39;)

codecs.register_error("cjk_replace", cjk_replace)

Of 물론, 이 논리는 실제로 충분히 엄격하지 않습니다. 이러한 혼합 인코딩의 이상을 처리하는 것이 다소 현실적이긴 하지만.

그런데 파이썬이 그런 기능을 제공하기 때문에 모두가 함께 토론할 수 있는데, 어떻게 하면 더 잘할 수 있을까요?

위 내용은 파이썬 블랙 매직 인코딩 변환 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.