8

"abc\udc34xyz"Python 2.7 では、Unicode 文字列を UTF-8 に正常に変換できます(結果は です"abc\xed\xb0\xb4xyz")。しかし、UTF-8文字列をegに渡すと。pango_parse_markup()またはg_convert_with_fallback()、「変換入力のバイト シーケンスが無効です」などのエラーが表示されます。どうやら GTK/Pango 関数は、文字列内の「対になっていないサロゲート」を検出し、(正しく?) それを拒否します。

"abc\udc34xyz".encode("utf8", "replace")Python 3 では、Unicode 文字列を UTF-8 に変換することさえできません (エラー: "'utf-8' コーデックは、位置 3 の文字 '\udc34' をエンコードできません: サロゲートは許可されていません")。唯一のサロゲートを他の文字に置き換えた有効な UTF8 文字列を取得します。それは私にとっては問題ありませんが、Python 2 のソリューションが必要です。

問題は、Python 2.7 で、唯一のサロゲートを U+FFFD のような置換文字に置き換えながら、その Unicode 文字列を UTF-8 に変換するにはどうすればよいかということです。できれば、標準の Python 関数と GTK/GLib/G... 関数のみを使用する必要があります。

ところで。Iconv は文字列を UTF8 に変換できますが、U+FFFD に置き換えるのではなく、単に悪い文字を削除するだけです。

4

1 に答える 1

10

エンコードする前に自分で置換を行うことができます:

import re

lone = re.compile(
    ur'''(?x)            # verbose expression (allows comments)
    (                    # begin group
    [\ud800-\udbff]      #   match leading surrogate
    (?![\udc00-\udfff])  #   but only if not followed by trailing surrogate
    )                    # end group
    |                    #  OR
    (                    # begin group
    (?<![\ud800-\udbff]) #   if not preceded by leading surrogate
    [\udc00-\udfff]      #   match trailing surrogate
    )                    # end group
    ''')

u = u'abc\ud834\ud82a\udfcdxyz'
print repr(u)
b = lone.sub(ur'\ufffd',u).encode('utf8')
print repr(b)
print repr(b.decode('utf8'))

出力:

u'abc\ud834\U0001abcdxyz'
'abc\xef\xbf\xbd\xf0\x9a\xaf\x8dxyz'
u'abc\ufffd\U0001abcdxyz'
于 2013-09-07T14:04:57.197 に答える