В стандартной библиотеке нет простого способа преобразовать этот формат данных в JSON, поэтому нам нужно написать синтаксический анализатор. Однако, поскольку формат данных довольно прост, это не сложно сделать. Мы можем использовать стандартный модуль csv
для чтения данных. csv.reader
будет корректно обрабатывать детали пробелов и строк в кавычках. Строка в кавычках будет обрабатываться как один токен, токены, состоящие из одного слова, могут быть заключены в кавычки, но это не обязательно.
csv.reader
обычно получает свои данные из открытого файла, но он достаточно универсален и также считывает свои данные из списка строк. Это удобно при тестировании, поскольку мы можем встроить наши входные данные в скрипт.
Мы анализируем данные во вложенном словаре. Простой способ отследить вложение - это использовать стек, и мы можем использовать простой список в качестве нашего стека.
В приведенном ниже коде предполагается, что строки ввода могут иметь одну из трех форм:
- Обычные данные. Строка состоит из пары ключ-значение, разделенной хотя бы одним пробелом.
- Новый подобъект. Строка начинается с ключа и заканчивается открытой скобкой
{
.
- Конец текущего подобъекта. Строка содержит одну закрывающую скобку
}
import csv
import json
raw = '''\
name {
first_name: "random"
}
addresses {
location {
locality: "India"
street_address: "xyz"
postal_code: "300092"
full_address: "street 1 , abc,India"
}
}
projects {
url: "www.githib.com"
}
'''.splitlines()
# A stack to hold the parsed objects
stack = [{}]
reader = csv.reader(raw, delimiter=' ', skipinitialspace=True)
for row in reader:
#print(row)
key = row[0]
if key == '}':
# The end of the current object
stack.pop()
continue
val = row[-1]
if val == '{':
# A new subobject
stack[-1][key] = d = {}
stack.append(d)
else:
# A line of plain data
stack[-1][key] = val
# Convert to JSON
out = json.dumps(stack[0], indent=4)
print(out)
выход
{
"name": {
"first_name:": "random"
},
"addresses": {
"location": {
"locality:": "India",
"street_address:": "xyz",
"postal_code:": "300092",
"full_address:": "street 1 , abc,India"
}
},
"projects": {
"url:": "www.githib.com"
}
}