Python / Json: Nama properti yang diharapkan diapit tanda kutip ganda

121

Saya telah mencoba mencari cara yang baik untuk memuat objek JSON dengan Python. Saya mengirim data json ini:

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

ke backend di mana itu akan diterima sebagai string lalu saya menggunakannya json.loads(data)untuk menguraikannya.

Tetapi setiap kali saya mendapat pengecualian yang sama:

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Saya mencarinya di Google tetapi tidak ada yang berhasil selain solusi ini json.loads(json.dumps(data))yang secara pribadi menurut saya tidak seefisien itu karena menerima semua jenis data bahkan yang tidak dalam format json.

Setiap saran akan sangat dihargai.

raeX
sumber
21
Kesalahan saya bukanlah kutipan ganda. Saya menambahkan koma setelah pasangan nilai kunci terakhir seperti yang kita lakukan di python. Anda tidak melakukannya di JSON.
Luv33preet
5
selalu gunakan json.dumps()daripada hanya menulis python dan berharap bahwa notasi python akan berfungsi di pembaca JavaScript Anda.
vy32
Saya mengalami masalah ini karena saya mengambil hasil a print(jsonpickle_deserialized_object_string)dan mencoba menggunakannya. Untuk beberapa alasan print()mengubah kutipan dari "menjadi'
StingyJack
@ Luv33preet, terima kasih, sudah diselesaikan. tapi saya mengharapkan logger-msg sebagai hilang-koma atau semacamnya, tapi kesalahan ini tidak memberitahu apapun tentang itu,
ganeshdeshmukh
lihat stackoverflow.com/a/63862387/1497139 untuk perbaikan cepat
Wolfgang Fahl

Jawaban:

162

Ini:

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

bukan JSON.
Ini:

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

adalah JSON.

EDIT:
Beberapa komentator menyarankan bahwa hal di atas tidak cukup.
Spesifikasi JSON - RFC7159 menyatakan bahwa string dimulai dan diakhiri dengan tanda kutip. Begitulah ".
Quoute tunggal 'tidak memiliki arti semantik di JSON dan hanya diperbolehkan di dalam string.

ElmoVanKielmo
sumber
4
Thanx :) Saya tidak memperhatikannya, saya menggunakan format json yang benar saat mengirim data tetapi ketika diterima di backend, tanda kutip ganda diganti dengan yang tunggal! oleh karena itu saya mendapat pengecualian itu.
raeX
38
ini bukanlah solusi. Sebuah solusi akan memberitahunya bagaimana memodifikasi string menjadi json yang valid.
FistOfFury
2
@FistOfFury Maaf, tetapi pernyataan Anda didasarkan pada asumsi yang salah bahwa string JSON yang tidak valid dapat diubah secara andal secara terprogram menjadi yang valid. Banyak sekali jawaban untuk pertanyaan ini mencoba untuk mengatasi masalah dengan mengganti 'dengan "dan sebagainya. Apakah saya harus memberikan contoh string input sederhana yang akan memutus" solusi "ini? Rupanya OP mengerti bahwa yang kita hadapi tidak JSON dan dapat melanjutkan - menerima jawaban saya. Petunjuk - string input lebih mirip keluaran metode Python dict .__ repr __ ().
ElmoVanKielmo
4
@ElmoVanKielmo tidak mengubah fakta bahwa jawaban Anda adalah pernyataan, bukan jawaban atas pertanyaan. Anda tidak memberikan konteks atau penjelasan. Orang yang datang ke sini untuk mencari informasi tentang pertanyaan itu akan kecewa. Anda mungkin telah membantu OP, tetapi yang lain tidak begitu banyak.
FistOfFury
Pernyataan sederhana yang jelas sering kali sangat membantu. Khususnya, jika ada banyak jawaban lain di sekitar.
Ben
56

karena JSON hanya mengizinkan string dengan tanda kutip ganda, Anda dapat memanipulasi string seperti ini:

str = str.replace("\'", "\"")

jika JSON Anda menahan tanda kutip tunggal ( \') yang lolos, Anda harus menggunakan kode berikut yang lebih tepat:

import re
p = re.compile('(?<!\\\\)\'')
str = p.sub('\"', str)

Ini akan mengganti semua kemunculan tanda kutip tunggal dengan tanda kutip ganda dalam string JSON strdan dalam kasus terakhir tidak akan mengganti tanda kutip tunggal yang di-escape.

Anda juga bisa menggunakan js-beautifyyang tidak terlalu ketat:

$ pip install jsbeautifier
$ js-beautify file.js
kelayakan
sumber
4
Bukan ide yang baik karena dapat menggantikan semua menjadi "yang salah: CONTOH: 'itu buruk' ->" itu buruk "-> string salah
format
@Reihan_amn Saya telah menambahkan alternatif regex yang lebih tepat untuk kasus di mana tanda kutip tunggal yang lolos digunakan.
Elig
@WolfgangFahl Anda dapat mencoba lagi sekarang.
Elig
thx Saya menggunakan stackoverflow.com/a/63862387/1497139 sebagai gantinya sekarang
Wolfgang Fahl
Saya menambahkan test case testSingleQuoteToDoubleQuoteStackoverflow ke github.com/WolfgangFahl/pyLoDStorage/blob/master/tests/… sesuai diskusi di stackoverflow.com/a/63862387/1497139, ini menunjukkan perbedaan hasil: {' Cities ': [{' name ': "Upper Hell's Gate"}, {' name ': "N'zeto"}] {"cities": [{"name": "Upper Hell's Gate"}, {"name": "N'zeto" }] {"Cities": [{"name": "Upper Hell" s Gate "}, {" name ":" N "zeto"}]
Wolfgang Fahl
35

Dalam kasus saya, tanda kutip ganda bukanlah masalah.

Koma terakhir memberi saya pesan kesalahan yang sama.

{'a':{'b':c,}}
           ^

Untuk menghapus koma ini, saya menulis beberapa kode sederhana.

import json

with open('a.json','r') as f:
    s = f.read()
    s = s.replace('\t','')
    s = s.replace('\n','')
    s = s.replace(',}','}')
    s = s.replace(',]',']')
    data = json.loads(s)

Dan ini berhasil untuk saya.

greentec
sumber
4
+1 Saya dapat mengkonfirmasi ini. Tanda koma menghasilkan pesan kesalahan ini. Contoh:, echo '{"json":"obj",}' | python -m json.tool ketika dijalankan di shell, berikan "Nama properti yang diharapkan diapit tanda kutip ganda: baris 1 kolom 15 (karakter 14)". Trailing commata bukanlah JSON legal, tetapi alangkah baiknya jika modul Python JSON mengeluarkan pesan kesalahan yang relevan dalam kasus ini.
Laryx Decidua
8

Sederhananya, string itu bukan JSON yang valid. Seperti kesalahannya, dokumen JSON perlu menggunakan tanda kutip ganda.

Anda perlu memperbaiki sumber datanya.

Daniel Roseman
sumber
7

Saya sudah memeriksa data JSON Anda

{'http://example.org/about': {'http://purl.org/dc/terms/title': [{'type': 'literal', 'value': "Anna's Homepage"}]}}

di http://jsonlint.com/ dan hasilnya adalah:

Error: Parse error on line 1:
{   'http://example.org/
--^
Expecting 'STRING', '}', got 'undefined'

memodifikasinya menjadi string berikut memecahkan kesalahan JSON:

{
    "http://example.org/about": {
        "http://purl.org/dc/terms/title": [{
            "type": "literal",
            "value": "Anna's Homepage"
        }]
    }
}
Yaron
sumber
2
TERIMA KASIH UNTUK TAUTAN TERSEBUT!
WolVes
7

String JSON harus menggunakan tanda kutip ganda. Pustaka python JSON memberlakukan ini sehingga Anda tidak dapat memuat string Anda. Data Anda harus terlihat seperti ini:

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}

Jika itu bukan sesuatu yang dapat Anda lakukan, Anda bisa menggunakan ast.literal_eval()bukannyajson.loads()

alexbclay.dll
sumber
3
Itu bukan batasan pustaka Python, tetapi format JSON itu sendiri.
Daniel Roseman
Anda benar. Namun, beberapa pengurai JSON tidak menerapkan tanda kutip ganda. Saya akan memperbarui jawaban saya.
alexbclay
asalkan bukan-JSON ini tidak pernah memiliki tanda kutip ganda di dalam string yang dikutip tunggal, yang harus Anda lakukan adalah mengganti string semua tunggal menjadi ganda sebelum memintajson.loads()
nigel222
2
Menggunakan ast.literal_evalakan menghasilkan ValueError: malformed stringjika string JSON memiliki nilai boolean.
Scratch'N'Purr
4
import ast

inpt = {'http://example.org/about': {'http://purl.org/dc/terms/title':
                                     [{'type': 'literal', 'value': "Anna's Homepage"}]}}

json_data = ast.literal_eval(json.dumps(inpt))

print(json_data)

ini akan menyelesaikan masalah.

balaji k
sumber
3

Seperti yang dikatakan dalam kesalahan, nama harus diapit tanda kutip ganda, bukan tanda kutip tunggal. String yang Anda berikan bukanlah JSON yang valid. Seharusnya terlihat seperti itu

{"http://example.org/about": {"http://purl.org/dc/terms/title": [{"type": "literal", "value": "Anna's Homepage"}]}}
Pavel Gurkov
sumber
2

Saya menggunakan metode ini dan berhasil mendapatkan hasil yang diinginkan. naskah saya

x = "{'inner-temperature': 31.73, 'outer-temperature': 28.38, 'keys-value': 0}"

x = x.replace("'", '"')
j = json.loads(x)
print(j['keys-value'])

keluaran

>>> 0
Hamed
sumber
2
with open('input.json','r') as f:
    s = f.read()
    s = s.replace('\'','\"')
    data = json.loads(s)

Ini bekerja dengan sangat baik untuk saya. Terima kasih.

rohit9786
sumber
2
x = x.replace("'", '"')
j = json.loads(x)

Meskipun ini adalah solusi yang tepat, tetapi mungkin akan membuat pusing jika ada JSON seperti ini -

{'status': 'success', 'data': {'equity': {'enabled': True, 'net': 66706.14510000008, 'available': {'adhoc_margin': 0, 'cash': 1277252.56, 'opening_balance': 1277252.56, 'live_balance': 66706.14510000008, 'collateral': 249823.93, 'intraday_payin': 15000}, 'utilised': {'debits': 1475370.3449, 'exposure': 607729.3129, 'm2m_realised': 0, 'm2m_unrealised': -9033, 'option_premium': 0, 'payout': 0, 'span': 858608.032, 'holding_sales': 0, 'turnover': 0, 'liquid_collateral': 0, 'stock_collateral': 249823.93}}, 'commodity': {'enabled': True, 'net': 0, 'available': {'adhoc_margin': 0, 'cash': 0, 'opening_balance': 0, 'live_balance': 0, 'collateral': 0, 'intraday_payin': 0}, 'utilised': {'debits': 0, 'exposure': 0, 'm2m_realised': 0, 'm2m_unrealised': 0, 'option_premium': 0, 'payout': 0, 'span': 0, 'holding_sales': 0, 'turnover': 0, 'liquid_collateral': 0, 'stock_collateral': 0}}}}

Memperhatikan bahwa nilai "Benar" ? Gunakan ini untuk membuat hal-hal diperiksa dua kali untuk Boolean. Ini akan mencakup kasus-kasus itu -

x = x.replace("'", '"').replace("True", '"True"').replace("False", '"False"').replace("null", '"null"')
j = json.loads(x)

Juga, pastikan Anda tidak membuatnya

x = json.loads(x)

Itu harus menjadi variabel lain.

Amit Ghosh
sumber
1

Saya punya masalah serupa. Dua komponen yang saling berkomunikasi menggunakan antrian.

Komponen pertama tidak melakukan json.dumps sebelum memasukkan pesan ke antrian. Jadi string JSON yang dihasilkan oleh komponen penerima berada dalam tanda kutip tunggal. Ini menyebabkan kesalahan

 Expecting property name enclosed in double quotes

Menambahkan json.dumps mulai membuat JSON yang diformat dengan benar & menyelesaikan masalah.

Rahul Bagal
sumber
0

Gunakan evalfungsinya.

Ini menangani perbedaan antara tanda kutip tunggal dan ganda.

msamogh.dll
sumber
JANGAN PERNAH menggunakan eval pada input pengguna atau data yang datang dengan permintaan HTTP. Ini adalah masalah keamanan yang sangat besar.
ElmoVanKielmo
0

Seperti jawaban lain menjelaskan dengan baik kesalahan terjadi karena karakter kutipan tidak valid diteruskan ke modul json.

Dalam kasus saya, saya terus mendapatkan ValueError bahkan setelah mengganti 'dengan "dalam string saya. Apa yang akhirnya saya sadari adalah bahwa beberapa simbol unicode seperti kutipan telah menemukan jalannya ke string saya:

 “  ”  ‛  ’  ‘  `  ´  ″  ′ 

Untuk membersihkan semua ini, Anda cukup meneruskan string Anda melalui ekspresi reguler:

import re

raw_string = '{“key”:“value”}'

parsed_string = re.sub(r"[“|”|‛|’|‘|`|´|″|′|']", '"', my_string)

json_object = json.loads(parsed_string)

Anders Solberg
sumber
-1

Saya telah mengalami masalah ini beberapa kali ketika JSON telah diedit dengan tangan. Jika seseorang menghapus sesuatu dari file tanpa menyadarinya dapat menimbulkan kesalahan yang sama.

Misalnya, Jika JSON "}" terakhir Anda tidak ada, ini akan memunculkan kesalahan yang sama.

Jadi Jika Anda mengedit file Anda dengan tangan pastikan Anda memformatnya seperti yang diharapkan oleh decoder JSON, jika tidak Anda akan mengalami masalah yang sama.

Semoga ini membantu!

Sneil
sumber
-2

Itu selalu ideal untuk menggunakan json.dumps()metode ini. Untuk menghilangkan kesalahan ini, saya menggunakan kode berikut

json.dumps(YOUR_DICT_STRING).replace("'", '"')
Michael Elimu
sumber