2016-07-01 38 views
14

これはConverting to Emojiへのフォローアップです。その質問では、OPにはjson.dumps() - サロゲートペアとして表された絵文字付きのエンコードファイル\ud83d\ude4fがありました。私はファイルを読み込んで絵文字を正しく翻訳していましたが、正確なanswerはファイルの各行にjson.loads()であり、jsonモジュールはサロゲートペアから(私はUTF8でエンコードされていると仮定しています)絵文字。だからここPythonでサロゲートペアを使用するにはどうすればいいですか?

は私の状況です:私はそれでサロゲートペアを持つだけで通常のPython 3のUnicode文字列を持っていると言う:

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

私はそれから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のようなエラーを取得します。

私は$LANGen_US.UTF-8に設定して、LinuxでPython 3.5.1を実行しています。これらのサンプルは、コマンドラインのPythonインタプリタとSublime Textで実行されるIPythonの両方で実行しました。違いはありません。メモリ内(Pythonのソースコード内の文字列リテラルを使用して指定)単一文字u'\ud83d'

答えて

21

あなたは、ディスク上のJSONファイルに(\ u d 8 3 d 6文字)文字列リテラル\ud83dを混合しました。あなたはバグが上流にあり'\ud83d\ude4f' Python文字列(文字)表示された場合、それは、Python 3

len(r'\ud83d') == 6len('\ud83d') == 1との間の差です。通常、そのような文字列を取得すべきではありません。あなたが1つを取得し、それを生成する上流を修正することはできません。

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

Python 2 was more permissive:あなたはsurrogatepassエラーハンドラを使用して、それを修正することができます。

注:jsonファイルにリテラル\ ud83d \ ude4f(文字)が含まれていても、あなたは、サロゲートペアを取得するべきではありません。

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

注意:結果は文字('\U0001f64f')、いないサロゲートペア('\ud83d\ude4f')です。

+0

恐ろしく、ありがとう! 'surrogatepass'エラーハンドラがありませんでした。 – MattDMo

関連する問題