pythonでescapeされた(?)文字列をunescape(?)する方法のメモ

時折変換の仕方などを忘れてしまい調べることなどがあるので。個人的なメモ。

JSONの文字列表現の文字列

JSONの文字列表現の文字列。なんて言えば良いんだろ?こういうやつ。

"{\"name\": \"foo\", \"age\": 20}"

とりあえず、unicode-escapeを使ってどうにかする。

>>> s = '"{\"name\": \"foo\", \"age\": 20}"'
>>> s.encode("utf-8").decode("unicode-escape").strip('"\n ')
'{"name": "foo", "age": 20}'

Unicodeリテラル

こういうやつ。これもunicode-escapeでdecodeしてあげるのが良い。

'\\u3042'

最初がstrならencodeでbytesにする必要がある。

>>> '\\u3042'.encode().decode("unicode-escape")
'あ'

# bytesのとき
>>> b'\\u3042'.decode("unicode-escape")
'あ'

たとえば、json.dumpsにensure_asciiを指定しなかった場合に現れたりする。

>>> import json
>>> json.dumps("あ")
'"\\u3042"'
>>> json.dumps("あ", ensure_ascii=False)
'"あ"'

もちろん、unicode-escapeでencodeしてあげても作れる。

>>> 'あ'.encode("unicode-escape")
b'\\u3042'

htmlなどでの数値文字参照(xmlcharref)

こういうやつ。wikipedia

'あ'

たまに、スクレイピングしていたりするとクローラーが保存する文字列がこの形になっている場合がある。あるいは何らかのAPIがこの表現で返ってくるということがある。

これはhtmlパッケージのunescapeを使うと良い。

>>> import html
>>> html.unescape('あ')
'あ'

ちなみにencode時のエラーハンドラーを利用してこの表現を作ることができる。

>>> 'あ'.encode("ascii", "xmlcharrefreplace")
b'あ'

# その他色々な表現も
>>> "あ".encode("ascii", "backslashreplace")
b'\\u3042'
>>> "あ".encode("ascii", "namereplace")
b'\\N{HIRAGANA LETTER A}'

詳しくはドキュメントのエラーハンドラーの部分

追記: URLクォート

これも一応ここに入れてしまう。こういうやつ。

'%E3%81%82'

URL上にマルチバイト文字を載せるときこの形式になることが多い。urllib.parseのquoteやunquoteを使う(空白も置き換えたい場合にはplusの方を)。

>>> import urllib.parse as p
>>> p.unquote('%E3%81%82')
'あ'

参考