16進をバイト列に

URL中の特殊文字はバイト列として % で始まる16進2桁で表します。例えばスペース(16進 0x20)は %20 になります。また,「日本語」という3文字は %E6%97%A5%E6%9C%AC%E8%AA%9E になります。この変換および逆変換は urllib.parse.(un)quote または requests.utils.(un)quote で行います:

import requests

requests.utils.quote("日本語")
'%E6%97%A5%E6%9C%AC%E8%AA%9E'
requests.utils.unquote('%E6%97%A5%E6%9C%AC%E8%AA%9E')
'日本語'

この unquote に相当することは Ruby では s.gsub(/%([0-9A-F][0-9A-F])/) { [$1].pack("H*") } のようにコンパクトに書けます。Python でもこんなに簡単に書ければいいのですが,なかなか難しそうです。次のようなことはできそうです:

import re
import struct

s = "%E6%97%A5%E6%9C%AC%E8%AA%9E"

re.sub(b"%([0-9A-F][0-9A-F])",
       lambda m: struct.pack("B", int(m[1], 16)),
       s.encode()).decode()
'日本語'

Last modified: