Python / Json: Đặt tên thuộc tính trong dấu ngoặc kép


110

Tôi đã cố gắng tìm ra một cách tốt để tải các đối tượng JSON bằng Python. Tôi gửi dữ liệu json này:

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

đến phần phụ trợ nơi nó sẽ được nhận dưới dạng một chuỗi sau đó tôi đã sử dụng json.loads(data)để phân tích cú pháp nó.

Nhưng mỗi lần tôi lại có cùng một ngoại lệ:

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

Tôi đã googled nó nhưng dường như không có gì hoạt động ngoài giải pháp này json.loads(json.dumps(data))mà theo cá nhân tôi, nó có vẻ không hiệu quả vì nó chấp nhận bất kỳ loại dữ liệu nào ngay cả những dữ liệu không có định dạng json.

Bất kỳ đề xuất sẽ được nhiều đánh giá cao.


18
Sai lầm của tôi không phải là điều báo giá kép. Tôi đã thêm dấu phẩy sau cặp khóa-giá trị cuối cùng giống như chúng ta làm trong python. Bạn không làm điều đó trong JSON.
Luv33preet

4
luôn sử dụng json.dumps()thay vì chỉ viết ra python và hy vọng rằng ký hiệu python sẽ hoạt động trong trình đọc JavaScript của bạn.
vy32 Ngày

Tôi gặp sự cố này vì tôi đã lấy kết quả của a print(jsonpickle_deserialized_object_string)và cố gắng sử dụng nó. Đối với một số lý do print()thay đổi các dấu ngoặc kép từ "đến'
StingyJack

@ Luv33preet, cảm ơn, đã giải quyết được. nhưng tôi mong đợi logger-msg là thiếu dấu phẩy hoặc cái gì đó, nhưng lỗi này không cho biết gì về nó,
ganeshdeshmukh

xem stackoverflow.com/a/63862387/1497139 để có bản sửa lỗi nhanh
Wolfgang Fahl

Câu trả lời:


150

Điều này:

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

không phải là JSON.
Điều này:

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

là JSON.

CHỈNH SỬA:
Một số người bình luận cho rằng những điều trên là không đủ.
Đặc tả JSON - RFC7159 nói rằng một chuỗi bắt đầu và kết thúc bằng dấu ngoặc kép. Đó là ".
Quoute đơn 'không có ý nghĩa ngữ nghĩa trong JSON và chỉ được phép bên trong một chuỗi.


4
Thanx :) Tôi không chú ý đến điều đó, tôi đang sử dụng đúng định dạng json khi gửi dữ liệu nhưng khi nó được nhận ở phần phụ trợ, dấu ngoặc kép được thay thế bằng dấu nháy đơn! do đó tôi có ngoại lệ đó.
raeX

25
đây không phải là một giải pháp. Một giải pháp sẽ cho anh ta biết cách sửa đổi chuỗi thành json hợp lệ.
FistOfFury vào

2
@FistOfFury Tôi xin lỗi nhưng tuyên bố của bạn dựa trên một giả định sai rằng chuỗi JSON không hợp lệ tùy ý có thể được lập trình biến thành chuỗi hợp lệ một cách đáng tin cậy. Rất nhiều câu trả lời cho câu hỏi này cố gắng giải quyết vấn đề bằng cách thay thế 'bằng ", v.v. Tôi có phải cung cấp cho bạn các ví dụ đơn giản về chuỗi đầu vào sẽ phá vỡ các" giải pháp "này không? Rõ ràng OP hiểu rằng những gì chúng ta đang giải quyết không phải là JSON và có thể tiếp tục - đã chấp nhận câu trả lời của tôi. Gợi ý - chuỗi đầu vào trông giống đầu ra của phương thức Python dict .__ repr __ ().
ElmoVanKielmo

4
@ElmoVanKielmo không thay đổi thực tế rằng câu trả lời của bạn là một tuyên bố, không phải là câu trả lời cho câu hỏi. Bạn không cung cấp ngữ cảnh hoặc giải thích. Mọi người đến đây tìm kiếm thông tin về câu hỏi sẽ thất vọng. Bạn có thể đã giúp OP, nhưng những người khác thì không nhiều.
FistOfFury

Một tuyên bố rõ ràng đơn giản thường giúp ích rất nhiều. Đặc biệt, khi có rất nhiều câu trả lời khác xung quanh.
Ben

47

vì JSON chỉ cho phép bao gồm các chuỗi có dấu ngoặc kép, bạn có thể thao tác chuỗi như thế này:

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

nếu JSON của bạn giữ dấu ngoặc kép ( \') thoát thì bạn nên sử dụng mã sau chính xác hơn:

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

Điều này sẽ thay thế tất cả các lần xuất hiện của dấu nháy đơn bằng dấu nháy kép trong chuỗi JSON strvà trong trường hợp thứ hai sẽ không thay thế dấu nháy đơn thoát.

Bạn cũng có thể sử dụng js-beautifycái ít nghiêm ngặt hơn:

$ pip install jsbeautifier
$ js-beautify file.js

4
Không phải là một ý kiến ​​hay vì nó có thể thay thế all 's thành "s, điều này là sai: EXAMPLE:' it bad '->" it "s bad" -> chuỗi không đúng định dạng
Reihan_amn

@Reihan_amn Tôi đã thêm một giải pháp thay thế regex chính xác hơn cho các trường hợp sử dụng dấu ngoặc đơn thoát.
elig

regexp báo lỗi cú pháp
Wolfgang Fahl

@WolfgangFahl, bạn có thể thử lại ngay bây giờ.
elig

thx Tôi đang sử dụng stackoverflow.com/a/63862387/1497139 thay vì ngay bây giờ
Wolfgang Fahl

33

Trong trường hợp của tôi, dấu ngoặc kép không phải là vấn đề.

Dấu phẩy cuối cùng cho tôi một thông báo lỗi.

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

Để loại bỏ dấu phẩy này, tôi đã viết một số mã đơn giản.

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)

Và điều này đã làm việc cho tôi.


4
+1 Tôi có thể xác nhận điều này. Dấu phẩy ở cuối tạo ra thông báo lỗi này. Ví dụ:, echo '{"json":"obj",}' | python -m json.tool khi chạy trong shell, đưa ra "Tên thuộc tính mong đợi được đặt trong dấu ngoặc kép: dòng 1 cột 15 (ký tự 14)". Các dấu phẩy theo sau không phải là JSON hợp pháp, nhưng sẽ rất tuyệt nếu mô-đun Python JSON phát ra thông báo lỗi có liên quan trong trường hợp này.
Laryx Decidua

7

Rất đơn giản, chuỗi đó không phải là JSON hợp lệ. Như lỗi cho biết, tài liệu JSON cần sử dụng dấu ngoặc kép.

Bạn cần sửa nguồn dữ liệu.


6

Tôi đã kiểm tra dữ liệu JSON của bạn

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

trong http://jsonlint.com/ và kết quả là:

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

sửa đổi nó thành chuỗi sau để giải quyết lỗi JSON:

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

2
CẢM ƠN VÌ MỐI LÊN KẾT ĐÓ!
WolVes

6

Chuỗi JSON phải sử dụng dấu ngoặc kép. Thư viện Python JSON thực thi điều này để bạn không thể tải chuỗi của mình. Dữ liệu của bạn cần trông như sau:

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

Nếu đó không phải là điều bạn có thể làm, bạn có thể sử dụng ast.literal_eval()thay vìjson.loads()


3
Đó không phải là hạn chế của thư viện Python, mà là của chính định dạng JSON.
Daniel Roseman

Bạn nói đúng. Tuy nhiên, một số trình phân tích cú pháp JSON không thực thi dấu ngoặc kép. Tôi sẽ cập nhật câu trả lời của tôi.
alexbclay 14/09/2016

cung cấp này không-JSON không bao giờ có bất kỳ dấu ngoặc kép bên trong chuỗi đơn trích dẫn, tất cả các bạn phải làm là chuỗi thay thế tất cả các singles để đôi trước khi gọijson.loads()
nigel222

2
Việc sử dụng ast.literal_evalsẽ dẫn đến ValueError: malformed stringnếu chuỗi JSON có giá trị 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)

điều này sẽ giải quyết vấn đề.


3

Như nó đã nói rõ ràng do nhầm lẫn, tên nên được đặt trong dấu ngoặc kép thay vì dấu ngoặc kép. Chuỗi bạn vượt qua không phải là một JSON hợp lệ. Nó sẽ giống như

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

2

Tôi đã sử dụng phương pháp này và quản lý để có được đầu ra mong muốn. kịch bản của tôi

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

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

đầu ra

>>> 0

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

Điều này làm việc hoàn toàn tốt cho tôi. Cảm ơn.


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

Mặc dù đây là giải pháp chính xác, nhưng nó có thể dẫn đến khá đau đầu nếu có một JSON như thế này -

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

Nhận thấy rằng giá trị "True" ? Sử dụng điều này để làm cho mọi thứ được kiểm tra kỹ lưỡng cho Booleans. Điều này sẽ bao gồm những trường hợp -

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

Ngoài ra, hãy đảm bảo rằng bạn không làm

x = json.loads(x)

Nó phải là một biến khác.


1

Tôi đã có vấn đề tương tự. Hai thành phần giao tiếp với nhau bằng cách sử dụng một hàng đợi.

Thành phần đầu tiên không thực hiện json.dumps trước khi đưa thông báo vào hàng đợi. Vì vậy, chuỗi JSON được tạo bởi thành phần nhận nằm trong dấu ngoặc kép. Điều này đã gây ra lỗi

 Expecting property name enclosed in double quotes

Thêm json.dumps bắt đầu tạo JSON được định dạng chính xác và đã giải quyết được vấn đề.


0

Sử dụng evalchức năng.

Nó xử lý sự khác biệt giữa dấu nháy đơn và dấu ngoặc kép.


KHÔNG BAO GIỜ sử dụng eval trên đầu vào của người dùng cũng như dữ liệu đi kèm với yêu cầu HTTP. Đây là một vấn đề bảo mật rất lớn.
ElmoVanKielmo

0

Như các câu trả lời khác giải thích rõ, lỗi xảy ra do các ký tự trích dẫn không hợp lệ được chuyển đến mô-đun json.

Trong trường hợp của tôi, tôi tiếp tục nhận được ValueError ngay cả sau khi thay thế 'bằng "trong chuỗi của mình. Điều cuối cùng tôi nhận ra là một số ký hiệu unicode giống như dấu ngoặc kép đã tìm thấy đường vào chuỗi của tôi:

           `  ´     

Để làm sạch tất cả những điều này, bạn chỉ có thể chuyển chuỗi của mình qua một biểu thức chính quy:

import re

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

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

json_object = json.loads(parsed_string)

-1

Tôi đã gặp sự cố này nhiều lần khi JSON được chỉnh sửa bằng tay. Nếu ai đó xóa một cái gì đó khỏi tệp mà không nhận thấy nó có thể gây ra lỗi tương tự.

Ví dụ: Nếu JSON cuối cùng của bạn "}" bị thiếu, nó sẽ gây ra lỗi tương tự.

Vì vậy, nếu bạn chỉnh sửa tệp của mình bằng tay, hãy đảm bảo rằng bạn định dạng nó giống như mong đợi của bộ giải mã JSON, nếu không bạn sẽ gặp phải vấn đề tương tự.

Hi vọng điêu nay co ich!


-2

Nó luôn luôn là lý tưởng để sử dụng json.dumps()phương pháp. Để loại bỏ lỗi này, tôi đã sử dụng mã sau

json.dumps(YOUR_DICT_STRING).replace("'", '"')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.