この記事は主にpython黒魔術のエンコード変換を紹介し、興味のある友人はそれを参照してください
エンコード変換を行うために他の言語のライブラリを使用する場合、理解できません 通常処理される文字の種類は 2 つ (または 3 つ) だけです:
例外をスローする
代替文字に置き換える
source -> unicode -> destまず、
文字列を元のエンコードから Unicode に変換します。次に、Unicode をターゲットのエンコーディングに変換します。
最初のステップでは、通常、decode()またはunicode()これら2つの関数を使用して完了します。 2 番目のステップでは、
encode() 関数を使用して完了します。
errors と呼ばれるオプションのパラメーターがあります。公式の説明を見てください:
エラーは、別のエラーを設定するために与えられる可能性があります
。デフォルトは、エンコードエラーが発生することを意味する「strict」です
a UnicodeDecodeError。他の可能な値は、'ignore' と 'replace'
、コーデックに登録されている他の名前です。
UnicodeDecodeErrors を処理可能です。
このパラメータには通常、次の 3 つの値があります:
スキップを無視してください。
を?に置き換えます。
さて、最後の文を見ましたか?ショーが始まります! モジュールコーデックには register_error という関数があります。この機能を使用すると、ユーザーはカスタムのエラー処理方法を登録できます。 UnicodeDecodeError を処理するために使用されます。
codecs.register_error(name, error_handler)
の名前。デコード関数のエラーパラメータを埋めるために使用されます。
error_handler: 処理関数。この関数は例外パラメータを受け入れます。タプルには 2 つの要素があり、1 つ目はエラー修正された文字列であり、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,'cp936'), newpos)
if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5
return (unicode(sk,'big5'), newpos)
raise TypeError('unknown codec !')
codecs.register_error("cjk_replace", cjk_replace)
上記は、私がインターネットから
コピー
したものです。最初はとても良いと思いましたが、後になって、それが非常に無反省なアルゴリズムであることがわかりました。
例:
a = "你" # utf8编码:'\xe4\xbd\xa0' c = unicode(a[:2],'gbk') # 正常返回 c = unicode(a, 'gbk') # 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 ('gbk','gb18030', 'big5'): beg = e.start - 2 if beg >= 0: try: return unicode(e.object[beg:e.end], 'utf8'), e.end + 1 except: pass 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 src != 'gbk' and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK return (unicode(sk,'cp936'), newpos) if src != 'big5' and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5 return (unicode(sk,'big5'), newpos) raise TypeError('unknown codec !') codecs.register_error("cjk_replace", cjk_replace)もちろん、このロジックは実際には十分厳密ではありません。この混合エンコードの異常に対処するのは少し現実的ですが。
しかし、Python はそのような機能を提供しているので、どうすればもっと良くできるか、みんなで話し合うことができます
以上がPythonのブラックマジックエンコード変換方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。