programing

문자열 인코딩 및 디코딩?

sourcetip 2021. 1. 16. 11:15
반응형

문자열 인코딩 및 디코딩?


다음은 오류 메시지에 대한 나의 시도입니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

string.decode("ascii", "ignore")

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 37: ordinal not in range(128)

string.encode('utf-8', "ignore")

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 37: ordinal not in range(128)


를 디코딩 unicode할 수없고 str. 다른 방법으로 시도해보십시오 .


원래 질문에서 생략 된 모든 것을 추측하지만 Python 2.x를 가정 할 때 핵심은 오류 메시지를주의 깊게 읽는 것입니다. 특히 '인코딩'이라고 부르지 만 메시지에 '디코드'라고 표시되고 그 반대의 경우도 마찬가지입니다. 메시지에 포함 된 값의 유형.

첫 번째 예에서는 string유형이 unicode있고 바이트 문자열 유니 코드 로 변환하는 작업 인 디코딩을 시도했습니다 . 파이썬은 유용하게에 유니 코드 값을 변환하려고 str인코딩 기본 '아스키'를 사용하지만 문자열을 파이썬은 할 수 없음을 말한다 오류가있어 비 ASCII 문자가 포함되어 있기 때문에 인코딩 유니 코드 값입니다. 다음은 입력 문자열의 유형을 보여주는 예입니다.

>>> u"\xa0".decode("ascii", "ignore")

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    u"\xa0".decode("ascii", "ignore")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128)

두 번째 경우에는 바이트 문자열 인코딩 시도를 반대로 수행합니다. 인코딩은 유니 코드를 바이트 문자열로 변환하는 작업이므로 Python은 먼저 바이트 문자열을 유니 코드로 변환하려고 시도하고 ASCII 문자열을 제공하지 않았으므로 기본 ASCII 디코더가 실패합니다.

>>> "\xc2".encode("ascii", "ignore")

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    "\xc2".encode("ascii", "ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)

가져 decode오고 encode뒤로 이동하는 것 외에도 여기에 대한 대답의 일부는 실제로 인코딩을 사용하지 않는 것ascii 입니다. 아마도 당신이 원하는 것이 아닐 것입니다.

우선 str일반 텍스트 파일과 같은 방식으로 생각 하십시오. 실제로 첨부 된 인코딩이없는 바이트 묶음입니다. 그것이 해석되는 방법은 그것을 읽는 코드에 달려 있습니다. 이 단락이 무엇에 대해 말하는지 모르겠다면, Joel의 The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets에 대해 더 읽어보세요.

당연히 우리 모두는 그 엉망진창을 알고 있습니다. 대답은 적어도 메모리 내에서 모든 문자열에 대해 표준 인코딩을 사용하는 것입니다. 그것이 unicode들어오는 입니다. 저는 파이썬이 내부적으로 사용하는 인코딩을 정확히 추적하는 데 어려움을 겪고 있습니다. 그러나 이것에 대해서는 실제로 중요하지 않습니다. 요점은 특정 방식으로 해석되는 바이트 시퀀스라는 것을 알고 있다는 것입니다. 따라서 바이트가 아닌 문자 자체에 대해서만 생각하면됩니다.

문제는 실제로 두 가지 모두에 부딪친다는 것입니다. 일부 라이브러리는을 제공 str하고 일부는 str. 이것은 일련의 바이트를 스트리밍 할 때마다 (예 : 디스크에서 또는 웹 요청을 통해) 이해할 수 있습니다. 그래서 당신은 앞뒤로 번역 할 수 있어야합니다.

Enter codecs:이 두 데이터 유형 간의 번역 라이브러리입니다. 당신이 사용하는 encode바이트 (일련의 생성하는 str텍스트 문자열 (에서)를 unicode), 당신은 사용 decode(텍스트 문자열을 얻을 수 unicode(바이트 순서에서) str).

예를 들면 :

>>> s = "I look like a string, but I'm actually a sequence of bytes. \xe2\x9d\xa4"
>>> codecs.decode(s, 'utf-8')
u"I look like a string, but I'm actually a sequence of bytes. \u2764"

여기에 무슨 일이 벌어 졌었 나? 나는 파이썬에게 일련의 바이트를 주었고, " unicode이 바이트의 순서가 'utf-8'. 내가 요청한대로, 그 바이트 ( 하트 문자 )는 이제 유니 코드 코드 포인트로 표현되는 전체로 취급됩니다.

다른 방법으로 가자 :

>>> u = u"I'm a string! Really! \u2764"
>>> codecs.encode(u, 'utf-8')
"I'm a string! Really! \xe2\x9d\xa4"

파이썬에 유니 코드 문자열을주고 'utf-8'인코딩을 사용하여 문자열을 바이트 시퀀스로 변환하도록 요청했습니다 . 그래서 그랬고 이제 심장은 ASCII로 인쇄 할 수없는 바이트의 무리입니다. 그래서 대신 16 진수를 보여줍니다.

물론 다른 인코딩으로도 작업 할 수 있습니다.

>>> s = "I have a section \xa7"
>>> codecs.decode(s, 'latin1')
u'I have a section \xa7'
>>> codecs.decode(s, 'latin1')[-1] == u'\u00A7'
True

>>> u = u"I have a section \u00a7"
>>> u
u'I have a section \xa7'
>>> codecs.encode(u, 'latin1')
'I have a section \xa7'

( '\xa7'는 IS 섹션 문자 유니 코드와 라틴-1 모두는.)

따라서 질문에 대해서는 먼저 자신의 인코딩 str무엇인지 파악해야합니다 .

  • 파일에서 가져 왔나요? 웹 요청에서? 데이터베이스에서? 그런 다음 소스가 인코딩을 결정합니다. 소스의 인코딩을 확인하고이를 사용하여 unicode.

    s = [get from external source]
    u = codecs.decode(s, 'utf-8') # Replace utf-8 with the actual input encoding
    
  • Or maybe you're trying to write it out somewhere. What encoding does the destination expect? Use that to translate it into a str. UTF-8 is a good choice for plain text documents; most things can read it.

    u = u'My string'
    s = codecs.encode(u, 'utf-8') # Replace utf-8 with the actual output encoding
    [Write s out somewhere]
    
  • Are you just translating back and forth in memory for interoperability or something? Then just pick an encoding and stick with it; 'utf-8' is probably the best choice for that:

    u = u'My string'
    s = codecs.encode(u, 'utf-8')
    newu = codecs.decode(s, 'utf-8')
    

In modern programming, you probably never want to use the 'ascii' encoding for any of this. It's an extremely small subset of all possible characters, and no system I know of uses it by default or anything.

Python 3 does its best to make this immensely clearer simply by changing the names. In Python 3, str was replaced with bytes, and unicode was replaced with str.


That's because your input string can’t be converted according to the encoding rules (strict by default).

I don't know, but I always encoded using directly unicode() constructor, at least that's the ways at the official documentation:

unicode(your_str, errors="ignore")

ReferenceURL : https://stackoverflow.com/questions/11339955/string-encoding-and-decoding

반응형