1

私は問題があります。Unicode 2019 は次の文字です: '</p>

右シングルクォートです。UTF8 としてエンコードされます。しかし、二重にエンコードされるのではないかと心配しています。

>>> u'\u2019'.encode('utf-8')
'\xe2\x80\x99'
>>> u'\xe2\x80\x99'.encode('utf-8')
'\xc3\xa2\xc2\x80\xc2\x99'
>>> u'\xc3\xa2\xc2\x80\xc2\x99'.encode('utf-8')
'\xc3\x83\xc2\xa2\xc3\x82\xc2\x80\xc3\x82\xc2\x99'
>>> print(u'\u2019')
’
>>> print('\xe2\x80\x99')
’
>>> print('\xc3\xa2\xc2\x80\xc2\x99')
’
>>> '\xc3\xa2\xc2\x80\xc2\x99'.decode('utf-8')
u'\xe2\x80\x99'
>>> '\xe2\x80\x99'.decode('utf-8')
u'\u2019'

これが上記の原則です。

C#で太字の部分を行うにはどうすればよいですか?

UTF8 でエンコードされた文字列を取得し、バイト配列に変換し、それを文字列に変換してから、再度デコードするにはどうすればよいですか?

この方法を試してみましたが、出力が ISO-8859-1 に適していないようです...

    string firstLevel = "’";
    byte[] decodedBytes = Encoding.UTF8.GetBytes(firstLevel);

    Console.WriteLine(Encoding.UTF8.GetChars(decodedBytes));
    // ’

    Console.WriteLine(decodeUTF8String(firstLevel));
    //â�,��"�
    //I was hoping for this:
    //’

理解の更新:

Jon's は、私の最も基本的な質問である "ã¢â€â™" から "’ へ、そしてそこから "'" へと進むのを助けてくれました。

  1. 何が起こっているかを理解する
  2. 原罪を正す

1位頑張りました。

エンコード/デコード

私はこれらのような用語でとても混乱します。「En...」と「De...」という単純な理由で、暗号化/復号化などの用語と混同しています。翻訳元と翻訳先を忘れてしまいます。これらの開始点と終了点を混同しています。16 進数、文字エンティティ、コード ポイント、文字マップなどの他のあいまいな用語に関連している可能性があります。

定義を基本的なレベルで解決したかったのです。この質問のコンテキストでのエンコードとデコードは次のとおりです。

  1. デコード
    • C# {Encoding} に対応します。'''GetString'''(bytesArray)
    • Python stringObject.'''decode'''({Encoding}) に対応します。
    • バイトを入力として受け取り、上記の {Encoding} で表される「エンコーディング」と呼ばれる変換スキームに従って、出力として文字列表現に変換します。
    • バイト -> 文字列
  2. エンコード
    • C# {Encoding} に対応します。'''GetBytes'''(stringObject)
    • Python stringObject.'''encode'''({Encoding}) に対応します。
    • デコードの逆。
    • 文字列 -> バイト (Python を除く)

Python のバイトと文字列

したがって、エンコードとデコードは、バイトと文字列の間を行き来します。

Python は何が問題なのかを理解するのに役立ちましたが、エンコーディング/デコーディングの「基礎」についての理解を混乱させる可能性もありました。ジョンは次のように述べています。

Pythonが[バイナリデータとテキストデータの違い]を大幅に隠しているのが残念

これが、PEPが言うときの意味だと思います

Python の現在の文字列オブジェクトはオーバーロードされています。それらは、一連の文字と一連のバイトの両方を保持するのに役立ちます。この目的の過負荷は、混乱とバグにつながります。

Python 3.* は、この方法で文字列をオーバーロードしません。

パイソン 2.7

>>> #Encoding example. As a generalization, "Encoding" produce bytes.
>>> #In Python 2.7, strings are overloaded to serve as bytes
>>> type(u'\u2019'.encode('utf-8'))
<type 'str'>

パイソン 3.*

>>> #In Python 3.*, bytes and strings are distinct
>>> type('\u2019'.encode('utf-8'))
<class 'bytes'>

Python 2 と 3 のもう 1 つの重要な (関連する) 違いは、デフォルトのエンコーディングです。

>>>import sys
>>>sys.getdefaultencoding()

パイソン 2

'ascii'

パイソン3

'utf-8'

そして、Python 2 は「ascii」と言っていますが、それは特定のタイプの ASCII を意味すると思います。

  • これは、Jon がデコードに使用する range(256) をサポートする ISO-8859-1 を意味するものではありません (後述)。
  • これは、range(128) のみである、最も単純な種類の ASCII を意味します。

また、Python 3 では文字列をバイトと文字列の両方としてオーバーロードしなくなりましたが、インタープリターにより、何が起こっているかを無視して型間を移動することが簡単になります。すなわち

  • Python 2.* では、文字列の前に「u」を置くだけで、Unicode リテラルになります。
  • Python 3.* では、文字列の前に 'b' を付けるだけで、Bytes リテラルになります。

エンコーディングと C

Jon は、C# が UTF-16 を使用して、上記の「UTF-8 でエンコードされた文字列」のコメントを修正していると指摘しています。

すべての文字列は事実上 UTF-16 です。私の理解は次のとおりです。C#に文字列オブジェクト「s」がある場合、コンピューターのメモリには実際にはUTF-16マップのその文字に対応するバイトがあります。つまり、(バイトオーダーマークを含む??)feff0073.

彼はまた、私が要求したハッキン​​グ方法で ISO-8859-1 を使用しています。理由はわかりません。今、頭が痛いので、見通しがついたらまた来ます。

この投稿に戻ります。きちんと説明できていることを願っています。Wikiにしようか?

4

1 に答える 1