45

これは絵文字への変換 のフォローアップです。その質問では、OP にはjson.dumps()、サロゲート ペアとして表される絵文字を含む - エンコードされたファイルがありました - \ud83d\ude4f。彼女/彼はファイルを読んで絵文字を正しく翻訳するのに問題があり、正しい答えjson.loads()ファイルの各行にあり、jsonモジュールはサロゲート ペアから (UTF8 でエンコードされた) 絵文字への変換を処理します。

ここに私の状況があります: サロゲートペアを含む通常の Python 3 Unicode 文字列があるとします:

emoji = "This is \ud83d\ude4f, an emoji."

この文字列を処理して絵文字の表現を取得するにはどうすればよいですか? 私はこのようなものを取得しようとしています:

"This is , an emoji."
# or
"This is \U0001f64f, an emoji."

私はもう試した:

print(emoji)
print(emoji.encode("utf-8")) # also tried "ascii", "utf-16", and "utf-16-le"
json.loads(emoji) # and `.encode()` with various codecs

通常、次のようなエラーが表示されUnicodeEncodeError: XXX codec can't encode character '\ud83d' in position 8: surrogates no allowedます。

$LANGに設定して、LinuxでPython 3.5.1を実行していen_US.UTF-8ます。コマンド ラインの Python インタープリターと、Sublime Text で実行されている IPython 内の両方でこれらのサンプルを実行しましたが、違いはないようです。

4

2 に答える 2

57

\ud83dディスク上の json ファイル内のリテラル文字列 (6 文字: \ u d 8 3 d) と、メモリ内の単一文字u'\ud83d'(Python ソース コードで文字列リテラルを使用して指定)を混在させました。len(r'\ud83d') == 6len('\ud83d') == 1Python 3の違いです。

'\ud83d\ude4f'Python 文字列 ( 2文字) が表示される場合は、上流にバグがあります。通常、このような文字列は取得しないでください。それを取得し、それを生成するアップストリームを修正できない場合。surrogatepassエラーハンドラーを使用して修正できます:

>>> "\ud83d\ude4f".encode('utf-16', 'surrogatepass').decode('utf-16')
''

Python 2 はより寛容でした。

注: json ファイルにリテラル \ud83d\ude4f ( 12文字) が含まれていても; サロゲート ペアを取得しないでください。

>>> print(ascii(json.loads(r'"\ud83d\ude4f"')))
'\U0001f64f'

注意: 結果は1文字 ( '\U0001f64f') であり、サロゲート ペア ( ) ではありません'\ud83d\ude4f'

于 2016-07-01T14:28:45.337 に答える