জেএসএনে একক বনাম ডাবল উদ্ধৃতি


119

আমার কোড:

import simplejson as json

s = "{'username':'dfdsfdsf'}" #1
#s = '{"username":"dfdsfdsf"}' #2
j = json.loads(s)

#1 সংজ্ঞাটি ভুল

#2 সংজ্ঞা ঠিক

আমি শুনেছি পাইথনে সেই একক এবং দ্বৈত উদ্ধৃতিটি বিনিময়যোগ্য হতে পারে। কেউ কি আমাকে এই ব্যাখ্যা করতে পারেন?

উত্তর:


180

জেএসওএন সিনট্যাক্স পাইথন সিনট্যাক্স নয়। JSON এর স্ট্রিংগুলির জন্য ডাবল কোট প্রয়োজন।


4
তবে প্রথমটি এটি জেএসএনে একক উক্তি, আমি বিভ্রান্ত। যে একটি সংকলন পাস করতে পারেন কিন্তু দ্বিতীয়টি পারে না।
বিন চেন

7
এই নিশ্চয়তার জন্য আপনাকে ধন্যবাদ। সম্ভবত আমি একমাত্র আমদানি করছি str(dict)এবং evalএটিও চাই না। একটি সহজ .replace("'", '"')কৌশল করা উচিত।
isaaclw

8
এবং আমি খুব শীঘ্রই কথা বললাম। স্পষ্টতই এটি এর চেয়ে জটিল।
isaaclw

6
যদি আপনার চারপাশে ডাবল উক্তি ব্যবহার করতে হয় তবে আপনি json.dumps(..)দ্বিগুণ কল করতে পারবেন : import json; d = dict(tags=["dog", "cat", "mouse"]); print json.dumps(json.dumps(d))যা দেয়:"{\"tags\": [\"dog\", \"cat\", \"mouse\"]}"
rprasad

129

তুমি ব্যবহার করতে পার ast.literal_eval()

>>> import ast
>>> s = "{'username':'dfdsfdsf'}"
>>> ast.literal_eval(s)
{'username': 'dfdsfdsf'}

9
আমি এই উত্তরটি সর্বোত্তম পছন্দ করি: আপনার প্রায়শই পছন্দ হয় না: যদি কেউ আপনাকে একক উদ্ধৃতি দেয়, আপনি একক উদ্ধৃতি পেয়েছেন। হয় json.loads একটি অতিরিক্ত যুক্তি প্রয়োজন, অথবা আপনি এটি ব্যবহার করা উচিত। বিশ্বব্যাপী "" "প্রতিস্থাপন করা একটি বিপর্যয়, আগত তথ্যগুলি যেমন হয়:{ 'a' : 'this "string" really isn\'t!!!!' }
মার্ক গেরোলিমাটোস

@ মার্ক, এই পদ্ধতিটি "{'link':'<a href="mylink">http://my.com</a>'}"কী নেস্টেড কোটস উদাহরণস্বরূপ একটি কৃপণ পরিস্থিতির সাথে মানিয়ে নেওয়া যায় ? এই ক্ষেত্রে, ast.literal_evalসিনট্যাক্স ত্রুটি নিক্ষেপ করে
আলঙ্কালভিটি

4
এটি আমার কাছে সুরক্ষার ঝুঁকির মতো বলে মনে হচ্ছে।
জ্যাকসনহেনচেন

4
কিভাবে এই প্রশ্নের উত্তর দেয়? এটি জেএসএনে একক বনাম ডাবল উদ্ধৃতিগুলির সাথে কী করতে পারে? এই অ্যাস্ট পদ্ধতির সাহায্যে আপনি একটি স্ট্রিং থেকে পাইথন ড্যাক লোড করতে পারবেন, কিন্তু ওপির মূল সমস্যাটি হল স্ট্রিং # 1 বৈধ জেএসএন নয় যেখানে স্ট্রিং # 2 রয়েছে।
jschultz410

ast.literal_evalকোনও সুরক্ষা ঝুঁকি নয়, এটি evalহবে।
হাড় 225

48

আপনি ডাবল উদ্ধৃতি সহ JSON ডাম্প করতে পারেন:

import json

# mixing single and double quotes
data = {'jsonKey': 'jsonValue',"title": "hello world"}

# get string with all double quotes
json_string = json.dumps(data) 

13
এটি ভুল পথে যায় আপনি অজগর ডেটা স্ট্রাকচারকে জেএসএন-তে সিরিয়ালাইজ করছেন; মূল প্রশ্নটি পাইথন ডেটা স্ট্রাকচারগুলিকে জেএসওনকে ডিসিজায়ালাইজ করার বিষয়ে।
tedder42

5
ধারণাটি হবে পাইথনটিকে জসন.ডম্পসের সাহায্যে জেসসনে সিরিয়ালাইজ করা, তারপরে যখন এটি আরআর আকারে থাকে তখন এটিতে json.loads কল করুন।
জেহেল্ড

4
আপনি এখানে বুঝতে মিস। আপনি যদি জসন স্ট্রিংটি লোড করতে চান তবে এটি ডাবল উদ্ধৃতি হতে হবে। আপনি যা করছেন তা হ'ল জসন ডাম্প, জসন স্ট্রিং নয়।
লেজিটেমি

12

খারাপ জেসন সিনট্যাক্সের সমস্যা সমাধানের জন্য ডেমজসনও একটি ভাল প্যাকেজ:

pip install demjson

ব্যবহার:

from demjson import decode
bad_json = "{'username':'dfdsfdsf'}"
python_dict = decode(bad_json)

সম্পাদনা করুন:

demjson.decodeক্ষতিগ্রস্থ জসন এর জন্য একটি দুর্দান্ত সরঞ্জাম, তবে আপনি যখন জসন ডেটার বড় আমোর্টের সাথে ডিল করছেন তখন ast.literal_evalএকটি ভাল ম্যাচ এবং আরও দ্রুত is


4
demjson.decodeক্ষতিগ্রস্থ জসন জন্য একটি দুর্দান্ত সরঞ্জাম - তবে দশক বা কয়েক লক্ষ জাসন প্যাকেট জড়িত কাজের জন্য ast.literal_evalএটি অনেক দ্রুত। demjsonএটির জায়গা নেই তা বলার অপেক্ষা রাখে না: দ্রুত পদ্ধতিগুলি ব্যর্থ হলে আমি ফ্যালব্যাক হিসাবে এটি ব্যবহার করি।
এমজেউন্ডারলিচ

4
আসলে ডেমজন হ'ল অ্যাস্ট.লাইটার_এভাল এবং জসন.লোডগুলির বিরুদ্ধে পরীক্ষার পরিবর্তে আরও ভাল কাজ করেছে
মার্ওয়্যার

7

এখনও পর্যন্ত দেওয়া উত্তর সহ দুটি ইস্যু, উদাহরণস্বরূপ, যদি এই জাতীয় মানহীন JSON প্রবাহিত করে। কারণ তখন একজনকে আগত স্ট্রিং (পাইথন অভিধান নয়) ব্যাখ্যা করতে হতে পারে might

ইস্যু 1 - demjson: পাইথন 3.7 সহ। + এবং কনডা ব্যবহার করে আমি ডেমজনকে ইনস্টল করতে সক্ষম হইনি যেহেতু আপত্তিজনকভাবে এটি বর্তমানে পাইথন> 3.5 সমর্থন করে না। সুতরাং আমার সহজ সমাধানগুলির সাথে সমাধানের প্রয়োজন, উদাহরণস্বরূপ astএবং / অথবাjson.dumps

সংখ্যা 2 - astএবংjson.dumps : যদি কোনও জেএসওএন উভয়ই একক উদ্ধৃত হয় এবং কমপক্ষে একটি মানে একটি স্ট্রিং থাকে, যার পরিবর্তে একক উদ্ধৃতি থাকে তবে আমি খুঁজে পেয়েছি এমন একমাত্র সহজ তবে ব্যবহারিক সমাধান উভয়ই প্রয়োগ করা হচ্ছে:

নিম্নলিখিত উদাহরণে আমরা ধরে নিই lineযে আসন্ন JSON স্ট্রিং অবজেক্ট:

>>> line = str({'abc':'008565','name':'xyz','description':'can control TV\'s and more'})

পদক্ষেপ 1: ast.literal_eval()
পদক্ষেপ 2 ব্যবহার করে আগত স্ট্রিংটিকে অভিধানে json.dumpsরূপান্তর করুন: কী এবং মানগুলির নির্ভরযোগ্য রূপান্তরকরণের জন্য এটি প্রয়োগ করুন , তবে মানগুলির বিষয়বস্তুগুলিকে স্পর্শ না করে :

>>> import ast
>>> import json
>>> print(json.dumps(ast.literal_eval(line)))
{"abc": "008565", "name": "xyz", "description": "can control TV's and more"}

json.dumpsএকা কাজটি করবে না কারণ এটি JSON ব্যাখ্যা করে না, তবে কেবল স্ট্রিংটি দেখবে। অনুরূপ ast.literal_eval(): যদিও এটি JSON (অভিধান) সঠিকভাবে ব্যাখ্যা করে, এটি আমাদের যা প্রয়োজন তা রূপান্তর করে না।


4

আপনি এটি সেভাবে ঠিক করতে পারেন:

s = "{'username':'dfdsfdsf'}"
j = eval(s)

ইনজেকশন আক্রমণ এড়াতে সাহায্যের জন্য ev.literal_eval এর পরিবর্তে ব্যবহার করুন
সাইমন কিংবাবি

2

যেমনটি বলা হয়েছে, জেএসএন পাইথন সিনট্যাক্স নয়। আপনার JSON এ ডাবল উক্তি ব্যবহার করা উচিত। এর নির্মাতা (ইন-) প্রোগ্রামার জ্ঞানীয় ওভারলোডকে স্বাচ্ছন্দ্যে অনুমোদনযোগ্য সিনট্যাক্সের কঠোর সাবসেট ব্যবহার করার জন্য বিখ্যাত।


নীচে ব্যর্থ হতে পারে যদি JION স্ট্রিংগুলির মধ্যে একটিতে নিজেই @ জিয়ারো দ্বারা নির্দেশিত একক উক্তি থাকে। ব্যবহার করবেন না. কী কাজ করে না তার উদাহরণ হিসাবে এখানে রেখেছি।

এটি জেনে রাখা সত্যিই দরকারী যে জেএসএন স্ট্রিংয়ে কোনও একক উদ্ধৃতি নেই। বলুন, আপনি এটি ব্রাউজার কনসোল / যা-ই হোক না কেন এটি অনুলিপি করে আটকে দিয়েছেন। তারপরে, আপনি কেবল টাইপ করতে পারেন

a = json.loads('very_long_json_string_pasted_here')

এটি অন্যথায় ভাঙতে পারে যদি এটি একক উদ্ধৃতিও ব্যবহার করে।


4
এটি সত্য নয় যে জসন স্ট্রিংয়ে কোনও একক উদ্ধৃতি নেই। এটি নির্দিষ্ট ক্ষেত্রে সত্য হতে পারে তবে আপনি এটির উপর নির্ভর করতে পারবেন না। উদাহরণস্বরূপ, এটি বৈধ json:{"key": "value 'with' single quotes"}
জিয়ারো

2

এটি সত্যই ইওল ফাংশনটি ব্যবহার করে আমার সমস্যার সমাধান করেছে।

single_quoted_dict_in_string = "{'key':'value', 'key2': 'value2'}"
desired_double_quoted_dict = eval(single_quoted_dict_in_string)
# Go ahead, now you can convert it into json easily
print(desired_double_quoted_dict)

এটি খুব খারাপ উদাহরণ is কেউ যদি জানতে পারে যে আপনি জসন-তে অ্যাওল ব্যবহার করছেন এবং যদি কোনও বিকৃত জসন কোডযুক্ত কোডটি প্রেরণ করেন যা এভাল দ্বারা মূল্যায়ন করা হয়?
মেটোনিমি

1

আমি সম্প্রতি একটি খুব অনুরূপ সমস্যার বিরুদ্ধে এসেছি, এবং বিশ্বাস করি আমার সমাধানটি আপনার পক্ষেও কার্যকর হবে। আমার কাছে একটি পাঠ্য ফাইল ছিল যা ফর্মটিতে আইটেমের একটি তালিকা রয়েছে:

["first item", 'the "Second" item', "thi'rd", 'some \\"hellish\\" \'quoted" item']

আমি উপরেরটি একটি অজগর তালিকায় পার্স করতে চেয়েছিলাম তবে ইনপুটটিতে বিশ্বাস করতে না পারায় ওয়াল () এর প্রতি আগ্রহী ছিল না। আমি প্রথমে জেএসএন ব্যবহার করে চেষ্টা করেছি তবে এটি কেবল দ্বিগুণ উদ্ধৃত আইটেম গ্রহণ করে, তাই আমি এই নির্দিষ্ট মামলার জন্য আমার নিজের খুব সাধারণ লেক্সারটি লিখেছি (কেবল নিজের "স্ট্রিংটপারস" এ প্লাগ ইন করুন এবং আপনি আউটপুট তালিকা হিসাবে পাবেন: 'আইটেম')

#This lexer takes a JSON-like 'array' string and converts single-quoted array items into escaped double-quoted items,
#then puts the 'array' into a python list
#Issues such as  ["item 1", '","item 2 including those double quotes":"', "item 3"] are resolved with this lexer
items = []      #List of lexed items
item = ""       #Current item container
dq = True       #Double-quotes active (False->single quotes active)
bs = 0          #backslash counter
in_item = False #True if currently lexing an item within the quotes (False if outside the quotes; ie comma and whitespace)
for c in stringtoparse[1:-1]:   #Assuming encasement by brackets
    if c=="\\": #if there are backslashes, count them! Odd numbers escape the quotes...
        bs = bs + 1
        continue                    
    if (dq and c=='"') or (not dq and c=="'"):  #quote matched at start/end of an item
        if bs & 1==1:   #if escaped quote, ignore as it must be part of the item
            continue
        else:   #not escaped quote - toggle in_item
            in_item = not in_item
            if item!="":            #if item not empty, we must be at the end
                items += [item]     #so add it to the list of items
                item = ""           #and reset for the next item
            continue                
    if not in_item: #toggle of single/double quotes to enclose items
        if dq and c=="'":
            dq = False
            in_item = True
        elif not dq and c=='"':
            dq = True
            in_item = True
        continue
    if in_item: #character is part of an item, append it to the item
        if not dq and c=='"':           #if we are using single quotes
            item += bs * "\\" + "\""    #escape double quotes for JSON
        else:
            item += bs * "\\" + c
        bs = 0
        continue

আশা করি এটি কারও কাজে লাগবে। উপভোগ করুন!


এটি কী সরবরাহ করে যা আপনি ডকস.পাইথন.আর . / ২ / লাইব্রেরি / আস্তেHtml#ast.literal_eval থেকে পান না ?
চার্লস ডাফি


-4
import json
data = json.dumps(list)
print(data)

উপরের কোড স্নিপেট কাজ করা উচিত।


4
এটি দরকারী কিছু করতে পারে, তবে এটি যে প্রশ্ন করা হয়েছিল তার উত্তর দেয় না। সমস্যাটি স্ট্রিং দিয়ে শুরু হয়, তালিকা নয়।
রাহেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.