pythonの中国語文字符号化の問題を解決する

8153 ワード

:https://imlogm.github.io/%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E5%A4%84%E7%90%86/character-encoding/
要旨:最近、自然言語処理に関するプロジェクトをしていますが、中国語の符号化の問題を発見するには、本当によく勉強する必要があります.pythonを例に、pythonがプログラミングするときに中国語の符号化をどのように処理するかを簡単に紹介します.
キーワード:自然言語処理、文字符号化、python
1.文字コードから
正直に言うと、文字コードは大きな内容で、ブログだけでは全然話せません.ここで大物の文章を借ります:文字コードのノート:ASCII、UnicodeとUTF-8-チェンの1峰のログ
上の文章を読んだ後、文字コードについて一定の認識があると信じています.中国語の自然言語処理の中で、最もよく出会うのはASCII、Unicode、UTF-8、GB 2312、GBKなどです.このいくつかのコードは、関連する文章を検索することができます.私はここで紹介しません.いくつかのpythonのプログラムで、pythonで文字符号化の問題をどのように処理するかを直接説明します.
2.pythonのstrタイプとprintプロセスについて
例えば、プログラム:
# -*- coding:utf-8 -*-

s = "      "  # s str     
print(s)

#     :“      ”

このプログラムの変数sはstrタイプです.コンピュータ内部はすべてバイナリの0と1であることを知っています.strタイプはこのような0と1からなるバイナリバイトストリームです.つまり、ここでの変数sはコンピュータ内部でバイナリバイトであり、文字列ではありません.
pythonのインタラクティブなプログラミング環境であれば、実験をすることができます.
>>> s = "      "
>>> s
\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe6\xae\xb5\xe4\xb8\xad\xe6\x96\x87
\xはこの数が16進数であることを示し、\xe8はこの数が16進数「E 8」であることを示し、バイナリに変換して11101000となり、上の「xe 8xbfx 99xe 6x 98xafxe 4xb 8x 80xe 6xaexb 5xe 4xb 8xadxe 6x 96x 87」は変数sが表すバイトストリームであり、言い換えれば、文字列「これは中国語です」のutf-8符号化フォーマットでのバイナリ表現です.
ここで2つの問題が発生しました.
  • 変数sが付与された場合、中国語の文字列はどのようにバイナリバイトストリームになりますか?
  • 変数sを印刷するとき、バイナリバイトストリームはどのように中国語の文字列になりますか?

  • まず問題1です.変数sが付与されると、文字列は何らかの符号化方式で符号化(encode)されてバイナリバイトとなり、変数sに付与される.ここでの「ある符号化方式」は、strタイプに値を割り当てるときにutf-8の符号化方式を使用することをコンピュータに明示的に伝えるためにコードによって明示的に指摘されている.
    そして問題2です.変数sを印刷すると、バイナリバイトストリームは何らかの符号化方式で文字列に復号される.ここでの「何らかの符号化方式」はオペレーティングシステムによって指摘される.私が使っているubuntuシステムはutf-8の符号化方式を使っています.# -*- coding:utf-8 -*- の違いに注意してください.符号化方式は復号方式と同様にprintが正常に表示され、そうでなければ乱符号化が表示されます.
    まだよく分からないかもしれませんが、私たちは上のプログラムでもう1組の実験をします.各コンピュータのコマンドラインの符号化方式が違うので、ubuntuのシステムを使っています.符号化フォーマットはutf-8です.私のコンピュータを例に説明します.また,実験は命令行の状態で行うことに注意する.一部のideはスマートで、出力環境の符号化フォーマットを自動的に交換し、実験効果に達しない.
    最初のプログラムは上記と同じように、効果を見てみましょう.
    # -*- coding:utf-8 -*-
    
    #          utf-8
    
    s = "      "  # s str     ,        utf-8          ,   s
    
    print(s)    # s str     ,     s(           ),   utf-8        
    
    #     :“      ”

    そして、最初の行を変更します.
    # -*- coding:GBK -*-
    
    #          utf-8
    
    s = "      "  # s str     ,        GBK          ,   s
    
    print(s)    # s str     ,     s(           ),   utf-8        
    
    #     :    

    3つ目の実験を行います
    # -*- coding:utf-8 -*-
    
    #          GBK
    
    s = "      "  # s str     ,        utf-8          ,   s
    
    print(s)    # s str     ,     s(           ),   GBK        
    
    #     :    

    この3つのプログラムの違いを理解できると思います.
    2.unicodeタイプについて
    unicodeタイプはpythonの文字列タイプであり、コンピュータ内でもバイナリバイトである.ただしstrが単純なバイナリバイトであるのとは異なり、unicodeタイプは、特にucs 2またはucs 4符号化フォーマットによって符号化されたバイナリバイトを指す.
    pythonのインタラクティブプログラミング環境では、次の実験を行うことができます.
    >>> s = u"      "    #      u,    s unicode  
    >>> s
    u'\u8fd9\u662f\u4e00\u6bb5\u4e2d\u6587'

    上記strタイプの実験結果の とは異なり,ここでは\xが現れた.\uはunicode符号化テーブルの位置を表し、例えば\uはunicode符号化テーブルの8 fd 9という位置の文字を表す.
    pythonのunicodeタイプの変数は、中継局として存在します.例えば、utf-8符号化からGBK符号化に文字列を変換するには、次のようにします.
    # -*- coding:utf-8 -*-
    
    s = "      "  # s str     ,        utf-8          ,   s
    
    s.decode("utf-8")   #      s utf-8     unicode,   s str    unicode  
    
    s.encode("GBK")     # unicode     s  GBK           ,     s unicode    str  
    
    #     :    

    逆に、1つのGBK符号化文字列をutf-8に変換するのも同様で、unicodeを中継局とします.
    3. sys.setdefaultencoding(‘utf-8’)
    ネット上のいくつかのチュートリアルでは、中国語の符号化の問題に遭遇したとき、コードの冒頭にこのいくつかの文を加えます.
    # -*- coding:utf-8 -*-
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')

    君がやってみると,本当に問題を解決したが,君はこのいくつかの言葉が何の役に立つか分からない.
    最初の文\u8fd9の前の段落では、コードがutf-8形式で符号化されていることを明示的に説明するために、追加しない場合は、一般的にデフォルトの符号化asciiを採用します.asciiは中国語をサポートしていません.コードに中国語があるとエラーが発生します.
    次の3つの文で、最も重要なのは# -*- coding:utf-8 -*-で、デフォルトの復号方式をutf-8に変更することを目的としています.
    次の実験を見てみましょう.
    # -*- coding: utf-8 -*- 
    s = '    '  # s      utf-8             ,str  
    s.encode('GBK') # s      ,     encode。python     decode, s str    unicode  ,  GBK   str  

    pythonのデフォルトの復号方法は、次のコードで取得できます.
    import sys
    print(sys.getdefaultencoding())

    もしあなたが取得したデフォルトの復号方式がasciiであれば.では、
    # -*- coding: utf-8 -*- 
    s = "      "  # s      utf-8             ,str  
    s.encode("GBK") # s      ,     encode。python     decode, s str    unicode  ,  GBK   str  
    
    #            ascii,             ,        
    s.decode("ascii").encode("GBK")

    明らかに、プログラムは間違いを報告します:UnicodeDecodeError:‘ascii’codec can’t decode byte 0 xe 4 in position.
    解決方法1は、復号フォーマットを表示して示す.
    # -*- coding: utf-8 -*- 
    s = "      " 
    
    s.decode("utf-8").encode("GBK") 

    解決方法2、デフォルトの復号方式を修正する:
    # -*- coding: utf-8 -*- 
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    s = "      " 
    
    s.encode("GBK") 

    このいくつかの実験からsys.setdefaultencoding('utf-8')の役割を理解できるはずです.
    4.学習成果の検証
    pythonよくあるエンコードエラーセット-妙音のブログ
    上のリンクのブログで挙げたいくつかのエラーの例を見て、今あなたは一目でエラーポイントを見つけて、解決方法を与えることができますか?