Python / Json: คาดหวังว่าชื่อคุณสมบัติที่อยู่ในเครื่องหมายคำพูดคู่


129

ฉันพยายามหาวิธีที่ดีในการโหลดออบเจ็กต์ JSON ใน Python ฉันส่งข้อมูล json นี้:

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

ไปที่แบ็กเอนด์ซึ่งจะได้รับเป็นสตริงจากนั้นฉันใช้json.loads(data)เพื่อแยกวิเคราะห์

แต่ทุกครั้งที่ฉันมีข้อยกเว้นเหมือนกัน:

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

ฉัน googled แต่ดูเหมือนว่าจะไม่มีอะไรทำงานนอกจากโซลูชันนี้json.loads(json.dumps(data))ซึ่งโดยส่วนตัวแล้วดูเหมือนว่าสำหรับฉันจะไม่ค่อยมีประสิทธิภาพเนื่องจากมันรับข้อมูลประเภทใดก็ได้แม้แต่ข้อมูลที่ไม่ได้อยู่ในรูปแบบ json

ข้อเสนอแนะใด ๆ จะได้รับการชื่นชมมาก


24
ความผิดพลาดของฉันไม่ใช่สิ่งที่อ้างถึงสองครั้ง ฉันเพิ่มลูกน้ำหลังคู่คีย์ - ค่าสุดท้ายเหมือนที่เราทำใน python คุณไม่ได้ทำใน JSON
Luv33preet

6
ใช้เสมอjson.dumps()แทนที่จะเขียน python และหวังว่าสัญกรณ์ python จะทำงานในโปรแกรมอ่าน JavaScript ของคุณ
vy32

ฉันมีปัญหานี้เพราะฉันเอาผลลัพธ์ของ a print(jsonpickle_deserialized_object_string)และพยายามที่จะใช้มัน ด้วยเหตุผลบางประการprint()เปลี่ยนคำพูดจาก"เป็น'
StingyJack

@ Luv33preet ขอบคุณได้แก้ไขแล้ว แต่ฉันคาดหวังว่า logger-msg เป็นเครื่องหมายจุลภาคหรืออะไรบางอย่างที่ขาดหายไป แต่ข้อผิดพลาดนี้ไม่ได้บอกอะไรเกี่ยวกับเรื่องนี้
ganeshdeshmukh

ดูstackoverflow.com/a/63862387/1497139สำหรับการแก้ไขอย่างรวดเร็ว
Wolfgang Fahl

คำตอบ:


173

นี้:

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

ไม่ใช่ JSON
นี้:

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

คือ JSON

แก้ไข: ผู้
แสดงความคิดเห็นบางคนแนะนำว่าข้างต้นไม่เพียงพอ
ข้อกำหนด JSON - RFC7159ระบุว่าสตริงเริ่มต้นและลงท้ายด้วยเครื่องหมายคำพูด นั่นคือ".
quoute เดี่ยว'ไม่มีความหมายเชิงความหมายใน JSON และอนุญาตให้อยู่ในสตริงเท่านั้น


5
Thanx :) ฉันไม่ได้ใส่ใจกับสิ่งนั้นฉันใช้รูปแบบ json ที่ถูกต้องเมื่อส่งข้อมูล แต่เมื่อได้รับที่แบ็กเอนด์คำพูดคู่จะถูกแทนที่ด้วยคำพูดเดี่ยว! ดังนั้นฉันจึงได้รับข้อยกเว้นนั้น
raeX

50
นี่ไม่ใช่วิธีแก้ปัญหา วิธีแก้ปัญหาจะบอกวิธีแก้ไขสตริงเป็น json ที่ถูกต้อง
FistOfFury

3
@FistOfFury ฉันขอโทษ แต่คำพูดของคุณตั้งอยู่บนสมมติฐานที่ผิด ๆ ว่าสตริง JSON ที่ไม่ถูกต้องโดยพลการสามารถเปลี่ยนทางโปรแกรมให้เป็นสตริงที่ถูกต้องได้อย่างน่าเชื่อถือ คำตอบมากมายสำหรับคำถามนี้พยายามแก้ไขปัญหาโดยการแทนที่ "ด้วย" และอื่น ๆ ฉันต้องยกตัวอย่างสตริงอินพุตง่ายๆที่จะทำลาย "วิธีแก้ปัญหา" เหล่านี้หรือไม่เห็นได้ชัดว่า OP เข้าใจว่าสิ่งที่เรากำลังจัดการอยู่นั้นไม่ใช่ JSON และสามารถดำเนินการต่อได้ - ยอมรับคำตอบของฉันคำแนะนำ - สตริงอินพุตดูเหมือนเอาต์พุตของเมธอด Python dict .__ repr __ () มากกว่า
ElmoVanKielmo

5
@ElmoVanKielmo ไม่ได้เปลี่ยนความจริงที่ว่าคำตอบของคุณคือคำสั่งไม่ใช่คำตอบสำหรับคำถาม คุณไม่ต้องระบุบริบทหรือคำอธิบาย คนที่มาที่นี่เพื่อหาข้อมูลเกี่ยวกับคำถามจะต้องผิดหวัง คุณอาจช่วย OP แต่คนอื่น ๆ ไม่มาก
FistOfFury

คำชี้แจงง่ายๆที่ชัดเจนมักจะช่วยได้มาก โดยเฉพาะอย่างยิ่งเมื่อมีคำตอบอื่น ๆ มากมาย
เบ็น

59

เนื่องจาก JSON อนุญาตให้ใส่เฉพาะสตริงที่มีเครื่องหมายคำพูดคู่คุณสามารถจัดการสตริงได้ดังนี้:

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

หาก JSON ของคุณมีเครื่องหมายคำพูดเดี่ยวที่ใช้ Escape ( \') คุณควรใช้รหัสต่อไปนี้ที่แม่นยำยิ่งขึ้น:

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

สิ่งนี้จะแทนที่คำพูดเดี่ยวที่เกิดขึ้นทั้งหมดด้วยเครื่องหมายคำพูดคู่ในสตริง JSON strและในกรณีหลังจะไม่แทนที่เครื่องหมายคำพูดเดี่ยวที่ใช้ Escape

คุณยังสามารถใช้js-beautifyสิ่งที่เข้มงวดน้อยกว่า:

$ pip install jsbeautifier
$ js-beautify file.js

4
ไม่ใช่ความคิดที่ดีเพราะสามารถแทนที่ทั้งหมดเป็น "ซึ่งไม่ถูกต้อง: ตัวอย่าง: 'มันไม่ดี' ->" มัน "ไม่ดี" -> สตริงที่ผิดรูปแบบ
Reihan_amn

@Reihan_amn ฉันได้เพิ่มทางเลือก regex ที่แม่นยำยิ่งขึ้นสำหรับกรณีที่มีการใช้เครื่องหมายคำพูดเดี่ยวที่ใช้ Escape
เริ่ม

@WolfgangFahl คุณลองใหม่ได้แล้ว
สิทธิ์

ขอบคุณตอนนี้ฉันใช้stackoverflow.com/a/63862387/1497139แทน
Wolfgang Fahl

ฉันเพิ่มกรณีทดสอบ testSingleQuoteToDoubleQuoteStackoverflow ไปที่github.com/WolfgangFahl/pyLoDStorage/blob/master/tests/…ต่อการสนทนาในstackoverflow.com/a/63862387/1497139 ซึ่งแสดงความแตกต่างของผลลัพธ์: {'เมือง': [{' name ': "ประตูนรกชั้นบน"}, {' name ': "N'zeto"}] {"เมือง": [{"name": "ประตูนรกชั้นบน"}, {"name": "N'zeto" }] {"เมือง": [{"name": "Upper Hell" s Gate "}, {" name ":" N "zeto"}]
Wolfgang Fahl

36

ในกรณีของฉันอัญประกาศคู่ไม่ใช่ปัญหา

ลูกน้ำสุดท้ายทำให้ฉันมีข้อความแสดงข้อผิดพลาดเดียวกัน

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

ในการลบเครื่องหมายจุลภาคฉันเขียนโค้ดง่ายๆ

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)

และสิ่งนี้ได้ผลสำหรับฉัน


4
+1 ฉันสามารถยืนยันสิ่งนี้ได้ เครื่องหมายจุลภาคต่อท้ายสร้างข้อความแสดงข้อผิดพลาดนี้ ตัวอย่าง: echo '{"json":"obj",}' | python -m json.tool เมื่อรันในเชลล์ให้ "Expecting property name ที่อยู่ในเครื่องหมายคำพูดคู่: บรรทัด 1 คอลัมน์ 15 (ถ่าน 14)" คอมมาตาต่อท้ายไม่ใช่ JSON ตามกฎหมาย แต่จะเป็นการดีหากโมดูล Python JSON ส่งข้อความแสดงข้อผิดพลาดที่เกี่ยวข้องในกรณีนี้
Laryx Decidua

8

พูดง่ายๆคือสตริงนั้นไม่ใช่ JSON ที่ถูกต้อง ตามที่ระบุข้อผิดพลาดเอกสาร JSON จำเป็นต้องใช้เครื่องหมายอัญประกาศคู่

คุณต้องแก้ไขแหล่งที่มาของข้อมูล


7

ฉันได้ตรวจสอบข้อมูล JSON ของคุณแล้ว

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

ในhttp://jsonlint.com/และผลลัพธ์คือ:

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

การแก้ไขเป็นสตริงต่อไปนี้แก้ข้อผิดพลาด JSON:

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

2
ขอบคุณสำหรับลิงค์นั้น!
WolVes

7

สตริง JSON ต้องใช้เครื่องหมายคำพูดคู่ ไลบรารี JSON python บังคับใช้สิ่งนี้คุณจึงไม่สามารถโหลดสตริงของคุณได้ ข้อมูลของคุณต้องมีลักษณะดังนี้:

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

หากนั่นไม่ใช่สิ่งที่คุณทำได้คุณสามารถใช้ast.literal_eval()แทนได้json.loads()


3
นั่นไม่ใช่ข้อ จำกัด ของไลบรารี Python แต่เป็นรูปแบบ JSON เอง
Daniel Roseman

คุณถูก. อย่างไรก็ตามตัวแยกวิเคราะห์ JSON บางตัวไม่บังคับใช้เครื่องหมายคำพูดคู่ ฉันจะอัปเดตคำตอบของฉัน
alexbclay

หาก not-JSON นี้ไม่เคยมีเครื่องหมายอัญประกาศคู่ใด ๆ ภายในสตริงที่ยกมาเดี่ยวสิ่งที่คุณต้องทำคือสตริงแทนที่ซิงเกิ้ลทั้งหมดให้เป็นสองเท่าก่อนที่จะเรียกjson.loads()
nigel222

2
การใช้ ast.literal_evalจะส่งผลValueError: malformed stringให้สตริง JSON มีค่าบูลีนหรือไม่
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)

สิ่งนี้จะช่วยแก้ปัญหาได้


3

ตามที่ระบุไว้อย่างชัดเจนว่าเป็นข้อผิดพลาดควรใส่ชื่อไว้ในเครื่องหมายคำพูดคู่แทนที่จะเป็นเครื่องหมายคำพูดเดี่ยว สตริงที่คุณส่งผ่านไม่ใช่ JSON ที่ถูกต้อง ควรมีลักษณะดังนี้

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

2

ฉันใช้วิธีนี้และจัดการเพื่อให้ได้ผลลัพธ์ที่ต้องการ สคริปต์ของฉัน

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

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

เอาท์พุท

>>> 0

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

สิ่งนี้ทำงานได้ดีสำหรับฉัน ขอบคุณ.


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

แม้ว่านี่จะเป็นวิธีแก้ปัญหาที่ถูกต้อง แต่ก็อาจทำให้ปวดหัวได้มากหากมี JSON เช่นนี้ -

{'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}}}}

สังเกตว่า"จริง"ค่า? ใช้สิ่งนี้เพื่อทำให้สิ่งต่างๆถูกตรวจสอบซ้ำสำหรับบูลีน ซึ่งจะครอบคลุมกรณีเหล่านั้น -

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

ตรวจสอบให้แน่ใจว่าคุณไม่ได้ทำ

x = json.loads(x)

มันจะต้องมีตัวแปรอื่น


1

ฉันมีปัญหาที่คล้ายกัน ส่วนประกอบสองอย่างที่สื่อสารกันใช้คิว

ส่วนประกอบแรกไม่ได้ทำ json.dumps ก่อนที่จะใส่ข้อความลงในคิว ดังนั้นสตริง JSON ที่สร้างโดยส่วนประกอบการรับจึงอยู่ในเครื่องหมายคำพูดเดี่ยว สิ่งนี้ทำให้เกิดข้อผิดพลาด

 Expecting property name enclosed in double quotes

การเพิ่ม json.dumps เริ่มสร้าง JSON ที่มีรูปแบบถูกต้องและแก้ไขปัญหาได้แล้ว


0

ใช้evalฟังก์ชัน

ดูแลความแตกต่างระหว่างเครื่องหมายคำพูดเดี่ยวและคู่


ไม่เคยใช้ eval กับอินพุตของผู้ใช้หรือข้อมูลที่มาพร้อมกับคำขอ HTTP นี่เป็นปัญหาด้านความปลอดภัยอย่างมาก
ElmoVanKielmo

0

เนื่องจากคำตอบอื่น ๆ อธิบายได้ดีข้อผิดพลาดเกิดขึ้นเนื่องจากอักขระอัญประกาศที่ไม่ถูกต้องส่งผ่านไปยังโมดูล json

ในกรณีของฉันฉันยังคงได้รับ ValueError แม้ว่าจะแทนที่'ด้วย"สตริงแล้วก็ตาม สิ่งที่ฉันรู้ในที่สุดก็คือสัญลักษณ์ยูนิโคดที่เหมือนเครื่องหมายคำพูดบางตัวได้พบทางเข้าไปในสตริงของฉัน

 “  ”  ‛  ’  ‘  `  ´  ″  ′ 

ในการล้างสิ่งเหล่านี้ทั้งหมดคุณสามารถส่งสตริงของคุณผ่านนิพจน์ทั่วไป:

import re

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

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

json_object = json.loads(parsed_string)


-1

ฉันพบปัญหานี้หลายครั้งเมื่อมีการแก้ไข JSON ด้วยมือ หากมีคนลบบางอย่างออกจากไฟล์โดยไม่สังเกตเห็นอาจทำให้เกิดข้อผิดพลาดเดียวกันได้

ตัวอย่างเช่นหาก JSON สุดท้าย "}" ของคุณหายไปจะทำให้เกิดข้อผิดพลาดเดียวกัน

ดังนั้นหากคุณแก้ไขไฟล์ด้วยมือโปรดตรวจสอบให้แน่ใจว่าคุณได้จัดรูปแบบตามที่ตัวถอดรหัส JSON คาดไว้มิฉะนั้นคุณจะพบปัญหาเดียวกัน

หวังว่านี่จะช่วยได้!


-2

มันก็มักจะเหมาะที่จะใช้json.dumps()วิธีการ เพื่อกำจัดข้อผิดพลาดนี้ฉันใช้รหัสต่อไปนี้

json.dumps(YOUR_DICT_STRING).replace("'", '"')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.