私は各行にこのようなテキスト(映画のキャストを表す)があるファイルを持っています:
[{'cast_id': 23, 'character': "Roger 'Verbal' Kint", 'credit_id': '52fe4260c3a36847f8019af7', 'gender': 2, 'id': 1979, 'name': 'Kevin Spacey', 'order': 5, 'profile_path': '/x7wF050iuCASefLLG75s2uDPFUu.jpg'}, {'cast_id': 27, 'character': 'Edie's Finneran', 'credit_id': '52fe4260c3a36847f8019b07', 'gender': 1, 'id': 2179, 'name': 'Suzy Amis', 'order': 6, 'profile_path': '/b1pjkncyLuBtMUmqD1MztD2SG80.jpg'}]
有効なjson文字列に変換する必要があるため、必要な一重引用符のみを二重引用符に変換します(たとえば、Word Verbalを囲む一重引用符は変換しないでください。また、テキスト内の最終的なアポストロフィも変換しないでください)。
python 3.xを使用しています。正しい一重引用符のみを二重引用符に変換する正規表現を見つける必要があります。したがって、テキスト全体が有効なjson文字列になります。何か考えはありますか?
まず第一に、あなたが例として挙げた行は解析できません! _… 'Edie's Finneran' …
_には、何があっても構文エラーが含まれています。
入力を制御できると仮定すると、eval()
を使用してファイルを読み込むことができます。 (ただし、その場合、そもそもなぜ有効なJSONを生成できないのか不思議に思うでしょう…)
_>>> f = open('list.txt', 'r')
>>> s = f.read().strip()
>>> l = eval(s)
>>> import pprint
>>> pprint.pprint(l)
[{'cast_id': 23,
'character': "Roger 'Verbal' Kint",
...
'profile_path': '/b1pjkncyLuBtMUmqD1MztD2SG80.jpg'}]
>>> import json
>>> json.dumps(l)
'[{"cast_id": 23, "character": "Roger \'Verbal\' Kint", "credit_id": "52fe4260ca36847f8019af7", "gender": 2, "id": 1979, "name": "Kevin Spacey", "order": 5, "rofile_path": "/x7wF050iuCASefLLG75s2uDPFUu.jpg"}, {"cast_id": 27, "character":"Edie\'s Finneran", "credit_id": "52fe4260c3a36847f8019b07", "gender": 1, "id":2179, "name": "Suzy Amis", "order": 6, "profile_path": "/b1pjkncyLuBtMUmqD1MztDSG80.jpg"}]'
_
入力を制御できない場合、コードインジェクション攻撃にさらされる可能性があるため、これは非常に危険です。
そもそも有効なJSONを生成することが最善の解決策であることを強調することはできません。
eval()(user3850の回答に記載)とは別に、ast.literal_evalを使用できます。
これはスレッドで議論されています: pythonのeval()とast.literal_eval()を使用しますか?
また、OPが言及したものと同様のデータを持つKaggleコンペティションの次のディスカッションスレッドを見ることができます。
https://www.kaggle.com/c/tmdb-box-office-prediction/discussion/89313#latest-517927https://www.kaggle.com/c/ tmdb-box-office-prediction/Discussion/80045#latest-518338
import ast
def getJson(filepath):
fr = open(filepath, 'r')
lines = []
for line in fr.readlines():
line_split = line.split(",")
set_line_split = []
for i in line_split:
i_split = i.split(":")
i_set_split = []
for split_i in i_split:
set_split_i = ""
rev = ""
i = 0
for ch in split_i:
if ch in ['\"','\'']:
set_split_i += ch
i += 1
break
else:
set_split_i += ch
i += 1
i_rev = (split_i[i:])[::-1]
state = False
for ch in i_rev:
if ch in ['\"','\''] and state == False:
rev += ch
state = True
Elif ch in ['\"','\''] and state == True:
rev += ch+"\\"
else:
rev += ch
i_rev = rev[::-1]
set_split_i += i_rev
i_set_split.append(set_split_i)
set_line_split.append(":".join(i_set_split))
line_modified = ",".join(set_line_split)
lines.append(ast.literal_eval(str(line_modified)))
return lines
lines = getJson('test.txt')
for i in lines:
print(i)