teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

不備があったため追記

2018/02/17 02:06

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -10,4 +10,21 @@
10
10
 
11
11
  Python3(?)ではUTF16がstrの表現に用いられいると思いますが、BMP範囲外の文字はサロゲートペア(長さが2の文字列)で表現されていて、それぞれのUTF16文字コードがU+D800~U+DFFFの範囲になるということを利用したものです。
12
12
 
13
- 不備ありましたらご容赦を・・・
13
+ 不備ありましたらご容赦を・・・
14
+
15
+ ---
16
+ 追記:申し訳ありません。不備がありました。
17
+ Python3.6.3 LANG=ja_JP.UTF8でUTF-8のソースコード上にBMP範囲外の文字列リテラルを直接記述して、列挙してみたところ以下のようにサロゲートペアでなく単一の文字として扱われていました。
18
+
19
+ len('????') == 1
20
+ ord('????') == 0x1f40d
21
+
22
+ このため最初の回答の関数ではNGで次のようにしなくてはなりませんでした。
23
+ リスト2
24
+ ```Python
25
+ # BMP範囲外のUNICODE文字が1文字として扱われている場合
26
+ def leaveOnlyBMP(s):
27
+ return "".join(filter(lambda c: ord(c) < 0x10000, s))
28
+ ```
29
+
30
+ ソースコード上に直接書いたり外部からエンコーディングを指定して文字列を読み込んだ場合など、Python3の環境でサロゲートペアになることがあるのかないのかが自分にはわかってませんが、BMP以外を含めたユニコード全範囲の文字を単一のコードポイントとして扱う能力が今のPythonにはあるようなのでその条件下ではリスト2でないといけないと思いました。