問題
今回は以下のような文字列を json.loads()
してみたときにおきた問題があったときの対応をまとめました。
sample_text = '{"key": "value \t value"}'
再現させる
>>> import json >>> sample_text = '{"key": "value \t value"}' >>> >>> json.loads(sample_text) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/www/.pyenv/versions/3.6.5/lib/python3.6/json/__init__.py", line 354, in loads return _default_decoder.decode(s) File "/home/www/.pyenv/versions/3.6.5/lib/python3.6/json/decoder.py", line 339, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/home/www/.pyenv/versions/3.6.5/lib/python3.6/json/decoder.py", line 355, in raw_decode obj, end = self.scan_once(s, idx) json.decoder.JSONDecodeError: Invalid control character at: line 1 column 16 (char 15)
問題は、 valueに入っている \t
が入っていることが原因のようです。
以下 json moduleのドキュメントを読んでわかる通り、
strict が false (デフォルトは True) の場合、制御文字を文字列に含めることができます。ここで言う制御文字とは、'\t' (タブ)、'\n'、'\r'、'\0' を含む 0-31 の範囲のコードを持つ文字のことです。
json --- JSON エンコーダおよびデコーダ — Python 3.7.6 ドキュメント
との記述があります。
ということは、strictがTrue(default value)だった場合には含めることができないです。
解決策
>>> json.loads(sample_text, strict=False) {'key': 'value \t value'}
引数をデフォルトの true
から false
に変更すればjson loadsできるようになります。
ということで、defaultが True
の値を False
に設定してあげれば、json.laods()できるようになります。
Decoderのobjectには他にも以下のように引数もあります。
class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)
- 作者:Bill Lubanovic
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)