RSSの <content:encoded> の文字列が数値文字参照になっているので読める文字列に変換する
こんなやつ
大昔にRSSでシステム間連携を実装したときにハマった気がしたけど一切覚えてない。
content:encoded
にある メーガン妃
のような文字列はどうやら 符号化文字集合の一つである Unicode におけるその文字のCode Point を16進数で表示する 数値文字参照
という形式で出力されてるらしい。
- 数値文字参照
この数値文字参照を実際の文字に戻すには
文字符号化方式 vvvvvvvvvvvvvvvvvvvvv 文字 <-> Code Point <-> byte列 ^^^^^^^^^^^^^^^^^^^ 符号化文字集合
のうち Code Point > 文字
をすればよい。
Pythonでやる場合は unicodedata
モジュールを使って
def unicode_test(codepoint): import unicodedata #コードポイントを対応する文字の名前に変換 name = unicodedata.name(codepoint) #対応する名前に当てはまる文字を取得 letter = unicodedata.lookup(name) result = """ Unicode文字: {} 対応する文字の名前: {} """.format(letter, name) print(result)
とすると変換できる。
試してみる
>>> import re >>> pattern = '&#x([0-9A-F]{4});' >>> res = re.findall(pattern, 'メーガン妃') # 数値文字参照からCode Pointの16進数文字列部分だけ抜き出す >>> print(res) ['30E1', '30FC', '30AC', '30F3', '5983'] >>> m = map(lambda x: unicode_test(chr(int(x, 16))), res) #16進数文字列から16進数数値型に変換した上で、(Unicode)文字列に変換して上記の関数に渡してみる >>> print(list(m)) Unicode文字: メ 対応する文字の名前: KATAKANA LETTER ME Unicode文字: ー 対応する文字の名前: KATAKANA-HIRAGANA PROLONGED SOUND MARK Unicode文字: ガ 対応する文字の名前: KATAKANA LETTER GA Unicode文字: ン 対応する文字の名前: KATAKANA LETTER N Unicode文字: 妃 対応する文字の名前: CJK UNIFIED IDEOGRAPH-5983
できた。
Pythonの html.unescape()
を使うと 数値文字参照からコードポイント16進数文字列への変換
と コードポイント16進数文字列から文字に変換
を一気にやってくれるから便利。
Presto/HiveにはUTF-16を操作する関数が用意されてないっぽい
あるにはあったが、数値文字参照からコードポイント16進数文字列への変換
と コードポイント16進数文字列から文字に変換
をSQLでやるのは相当気合がいりそう(できるかどうかわからない)