first, your input isn't json. Json uses double quotes. But suppose you successfully loaded it with json, it's now a dictionary, called d.
Then you can scan all sub-dicts of d and test serial key against your value, stopping when found using any and a generator comprehension:
print(any(sd['serial']=='00000000762c1d3c' for sd in d['device']))
returns True if serial found False otherwise.
first, your input isn't json. Json uses double quotes. But suppose you successfully loaded it with json, it's now a dictionary, called d.
Then you can scan all sub-dicts of d and test serial key against your value, stopping when found using any and a generator comprehension:
print(any(sd['serial']=='00000000762c1d3c' for sd in d['device']))
returns True if serial found False otherwise.
date['device'] contains a list of objects, so you should treat it as such and iterate over them:
for element in data['device']:
if element['serial'] == '00000000762c1d3c':
print 'there'
print element['registered_id']
break
else:
print 'not there'
This is using the somehow lesser-known for-else construct: https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops
How to find JSON object in text with python - Stack Overflow
How to find and replace a specific string in a json file with python - Post.Byes
Find a value in JSON using Python - Stack Overflow
python - Parsing json and searching through it - Stack Overflow
Hi
I have a string that contains a lot of text, and then a json part. Is there an easy way to extract only the json part? or is substring the way to go? (im just having truble with it cutting off some of the brackets).
The output is a powershell script, that looks up some data in a exchange server, and then outputs the object a json string. But it also outputs some text on how the script has run, so i want to remove that part. (i have been unable to supress that part)
You found a regex that uses syntax that Python standard library re module doesn't support.
When you look at the regex101 link, you'll see that the pattern works when using the PRCE library, and the problematic (?R) syntax that throws the error uses a feature called recursion. That feature is only supported by a subset of regex engines.
You could install the regex library, an alternative regex engine for Python that explicitly does support that syntax:
>>> import regex
>>> pattern = regex.compile(r'\{(?:[^{}]|(?R))*\}')
>>> pattern.findall('''\
... This is a funny text about stuff,
... look at this product {"action":"product","options":{...}}.
... More Text is to come and another JSON string
... {"action":"review","options":{...}}
... ''')
['{"action":"product","options":{...}}', '{"action":"review","options":{...}}']
Another option is to just try and decode any section that starts with { using the JSONDecoder.raw_decode() method; see How do I use the 'json' module to read in one JSON object at a time? for an example approach. While the recursive regex can find JSON-like text, the decoder approach would let you extract only valid JSON text.
Here is a generator function that does just that:
from json import JSONDecoder
def extract_json_objects(text, decoder=JSONDecoder()):
"""Find JSON objects in text, and yield the decoded JSON data
Does not attempt to look for JSON arrays, text, or other JSON types outside
of a parent JSON object.
"""
pos = 0
while True:
match = text.find('{', pos)
if match == -1:
break
try:
result, index = decoder.raw_decode(text[match:])
yield result
pos = match + index
except ValueError:
pos = match + 1
Demo:
>>> demo_text = """\
This is a funny text about stuff,
look at this product {"action":"product","options":{"foo": "bar"}}.
More Text is to come and another JSON string, neatly delimited by "{" and "}" characters:
{"action":"review","options":{"spam": ["ham", "vikings", "eggs", "spam"]}}
"""
>>> for result in extract_json_objects(demo_text):
... print(result)
...
{'action': 'product', 'options': {'foo': 'bar'}}
{'action': 'review', 'options': {'spam': ['ham', 'vikings', 'eggs', 'spam']}}
If there is only one JSON in one line, you can use the index methods to find the first and the last bracket to select the JSON:
firstValue = jsonString.index("{")
lastValue = len(jsonString) - jsonString[::-1].index("}")
jsonString = jsonStringEncoded[firstValue:lastValue]
You have to iterate over the list of dictionaries and search for the one with the given id_number. Once you find it you can print the rest of its data and break, assuming id_number is unique.
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
for i in data:
if i['id_number'] == 'V410Z8':
print(i['birthdate'])
print(i['name'])
break
If you have control over the data structure, a more efficient way would be to use the id_number as a key (again, assuming id_number is unique):
data = { "SA4784" : {"name": "Mark", "birthdate": None},
"V410Z8" : { "name": "Vincent", "birthdate": "15/02/1989"},
"CZ1094" : {"name": "Paul", "birthdate": "27/09/1994"}
}
Then all you need to do is try to access it directly:
try:
print(data["V410Z8"]["name"])
except KeyError:
print("ID doesn't exist")
>> "Vincent"
Using lambda in Python
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
Using Lambda and filter
print(list(filter(lambda x:x["id_number"]=="CZ1094",data)))
Output
[{'id_number': 'CZ1094', 'name': 'Paul', 'birthdate': '27/09/1994'}]
ObjectPath is a library that provides ability to query JSON and nested structures of dicts and lists. For example, you can search for all attributes called "foo" regardless how deep they are by using $..foo.
While the documentation focuses on the command line interface, you can perform the queries programmatically by using the package's Python internals. The example below assumes you've already loaded the data into Python data structures (dicts & lists). If you're starting with a JSON file or string you just need to use load or loads from the json module first.
import objectpath
data = [
{'foo': 1, 'bar': 'a'},
{'foo': 2, 'bar': 'b'},
{'NoFooHere': 2, 'bar': 'c'},
{'foo': 3, 'bar': 'd'},
]
tree_obj = objectpath.Tree(data)
tuple(tree_obj.execute('$..foo'))
# returns: (1, 2, 3)
Notice that it just skipped elements that lacked a "foo" attribute, such as the third item in the list. You can also do much more complex queries, which makes ObjectPath handy for deeply nested structures (e.g. finding where x has y that has z: $.x.y.z). I refer you to the documentation and tutorial for more information.
As json.loads simply returns a dict, you can use the operators that apply to dicts:
>>> jdata = json.load('{"uri": "http:", "foo", "bar"}')
>>> 'uri' in jdata # Check if 'uri' is in jdata's keys
True
>>> jdata['uri'] # Will return the value belonging to the key 'uri'
u'http:'
Edit: to give an idea regarding how to loop through the data, consider the following example:
>>> import json
>>> jdata = json.loads(open ('bookmarks.json').read())
>>> for c in jdata['children'][0]['children']:
... print 'Title: {}, URI: {}'.format(c.get('title', 'No title'),
c.get('uri', 'No uri'))
...
Title: Recently Bookmarked, URI: place:folder=BOOKMARKS_MENU(...)
Title: Recent Tags, URI: place:sort=14&type=6&maxResults=10&queryType=1
Title: , URI: No uri
Title: Mozilla Firefox, URI: No uri
Inspecting the jdata data structure will allow you to navigate it as you wish. The pprint call you already have is a good starting point for this.
Edit2: Another attempt. This gets the file you mentioned in a list of dictionaries. With this, I think you should be able to adapt it to your needs.
>>> def build_structure(data, d=[]):
... if 'children' in data:
... for c in data['children']:
... d.append({'title': c.get('title', 'No title'),
... 'uri': c.get('uri', None)})
... build_structure(c, d)
... return d
...
>>> pprint.pprint(build_structure(jdata))
[{'title': u'Bookmarks Menu', 'uri': None},
{'title': u'Recently Bookmarked',
'uri': u'place:folder=BOOKMARKS_MENU&folder=UNFILED_BOOKMARKS&(...)'},
{'title': u'Recent Tags',
'uri': u'place:sort=14&type=6&maxResults=10&queryType=1'},
{'title': u'', 'uri': None},
{'title': u'Mozilla Firefox', 'uri': None},
{'title': u'Help and Tutorials',
'uri': u'http://www.mozilla.com/en-US/firefox/help/'},
(...)
}]
To then "search through it for u'uri': u'http:'", do something like this:
for c in build_structure(jdata):
if c['uri'].startswith('http:'):
print 'Started with http'
import json
import sys
import os
data = []
if os.stat("data.txt").st_size != 0 :
file = open('data.txt', 'r')
data = json.load(file)
print(data)
choice = input("What's your choice ?")
if choice == 'a':
# Add a new joke.
# See Point 3 of the "Requirements of admin.py" section of the assignment brief.
jokeSetup = input('Enter setup of joke: ')
jokePunchLine = input('Enter punchline of joke: ')
entry = {'setup': jokeSetup , 'punchline': jokePunchLine}
data.append(entry)
file = open('data.txt', 'w')
json.dump(data, file)
file.close()
print('Joke Added.')
pass
elif choice == 's':
# Search the current jokes.
# See Point 5 of the "Requirements of admin.py" section of the assignment brief.
searchTerm = input('Enter search term: ')
file = open('data.txt', 'r')
data = json.load(file)
file.close()
for sub_dict in data:
if searchTerm in sub_dict['setup']:
print(sub_dict['punchline'])
pass
# or you could modify the last for loop, like this:
for dict in data:
if searchTerm in dict['setup'] or searchTerm in dict['punchline']:
print('found!')
pass
You could do it like this:
if choice == 'a':
# Add a new joke.
# See Point 3 of the "Requirements of admin.py" section of the assignment brief.
jokeSetup = input('Enter setup of joke: ')
jokePunchLine = input('Enter punchline of joke: ')
entry = {'setup': jokeSetup , 'punchline': jokePunchLine}
data.append(entry)
file = open('data.txt', 'w')
json.dump(data, file)
file.close()
print('Joke Added.')
pass
elif choice == 's':
# Search the current jokes.
# See Point 5 of the "Requirements of admin.py" section of the assignment brief.
searchTerm = input('Enter search term: ')
file = open('data.txt', 'r')
data = json.load(file)
file.close()
for item in data[0].items():
if searchTerm in str(item[1]):
print ('found it')
pass
# or the for loop could be like this
for sub_dict in data:
if searchTerm in sub_dict['setup'] or searchTerm in sub_dict['punchline']:
print('found!')