Как преобразовать неверную строку JSON с одинарными кавычками в действительный JSON

Я случайно сохранил в своей базе данных строку, подобную JSON, в которой используются одинарные кавычки вместо двойных, и средства форматирования JSON не распознают ее как действительный JSON. Вот строка, которая у меня есть:

import json

json_string = """
{'author': 'Hebbars Kitchen', 'canonical_url': 'https://hebbarskitchen.com/til-chikki-recipe-sesame-chikki-gajak/', 'category': 'sweet', 'cook_time': 10, 'cuisine': 'Indian', 'description': 'easy til chikki recipe | sesame chikki recipe | til ki chikki or til gajak', 'host': 'hebbarskitchen.com', 'image': 'https://hebbarskitchen.com/wp-content/uploads/mainPhotos/til-chikki-recipe-sesame-chikki-recipe-til-ki-chikki-or-til-gajak-2.jpeg', 'ingredient_groups': [{'ingredients': ['1 cup sesame / til (white)', '1 tsp ghee / clarified butter', '1 cup jaggery / gud'], 'purpose': None}], 'ingredients': ['1 cup sesame / til (white)', '1 tsp ghee / clarified butter', '1 cup jaggery / gud'], 'instructions': 'firstly in a pan dry roast 1 cup sesame on low flame till it splutters.\nnow in another kadai heat 1 tsp ghee and add 1 cup jaggery.\nkeep stirring on medium flame till the jaggery melts completely. alternatively, use sugar, if you do not prefer jaggery.\nboil the jaggery syrup on low flame till the syrup turns glossy and thickens.\ncheck the consistency, by dropping syrup into a bowl of water, it should form hard ball and cut with a snap sound. else boil for another minute and check.\nsimmer the flame add add roasted sesame seeds.\nstir well making sure jaggery syrup coats well.\nimmediately pour the mixture over butter paper or onto steel plate greased with ghee. be quick else the mixture turns hard and will be difficult to set.\nget together forming a block, be careful as the mixture will be very hot.\nnow using a rolling pin roll the slightly thick block.\nallow to cool for a minute, and when its still warm cut into pieces.\nlastly, serve til chikki once cooled completely, or store in a airtight container and serve for a month.', 'instructions_list': ['firstly in a pan dry roast 1 cup sesame on low flame till it splutters.', 'now in another kadai heat 1 tsp ghee and add 1 cup jaggery.', 'keep stirring on medium flame till the jaggery melts completely. alternatively, use sugar, if you do not prefer jaggery.', 'boil the jaggery syrup on low flame till the syrup turns glossy and thickens.', 'check the consistency, by dropping syrup into a bowl of water, it should form hard ball and cut with a snap sound. else boil for another minute and check.', 'simmer the flame add add roasted sesame seeds.', 'stir well making sure jaggery syrup coats well.', 'immediately pour the mixture over butter paper or onto steel plate greased with ghee. be quick else the mixture turns hard and will be difficult to set.', 'get together forming a block, be careful as the mixture will be very hot.', 'now using a rolling pin roll the slightly thick block.', 'allow to cool for a minute, and when its still warm cut into pieces.', 'lastly, serve til chikki once cooled completely, or store in a airtight container and serve for a month.'], 'language': 'en-US', 'nutrients': {}, 'prep_time': 5, 'ratings': 5.0, 'ratings_count': 196, 'site_name': "Hebbar's Kitchen", 'title': 'til chikki recipe | sesame chikki recipe | til ki chikki or til gajak', 'total_time': 15, 'yields': '24 servings'}
"""

formatted_json = json.dumps(json_string)

print(formatted_json)

Строка содержит одинарные кавычки вместо двойных, что делает ее недействительным JSON. Я попытался использовать json.dumps() для его форматирования, но это просто преобразует строку в другую строку JSON, а не устраняет проблему.

Я также пробовал использовать ast.literal_eval и demjson3, похоже, ничего не работает.

Используя ast.literal_eval()

import json

# Assume your JSON string is stored in a variable called 'json_string'
json_string = """
{'author': 'Hebbars Kitchen', 'canonical_url': 'https://hebbarskitchen.com/til-chikki-recipe-sesame-chikki-gajak/', 'category': 'sweet', 'cook_time': 10, 'cuisine': 'Indian', 'description': 'easy til chikki recipe | sesame chikki recipe | til ki chikki or til gajak', 'host': 'hebbarskitchen.com', 'image': 'https://hebbarskitchen.com/wp-content/uploads/mainPhotos/til-chikki-recipe-sesame-chikki-recipe-til-ki-chikki-or-til-gajak-2.jpeg', 'ingredient_groups': [{'ingredients': ['1 cup sesame / til (white)', '1 tsp ghee / clarified butter', '1 cup jaggery / gud'], 'purpose': None}], 'ingredients': ['1 cup sesame / til (white)', '1 tsp ghee / clarified butter', '1 cup jaggery / gud'], 'instructions': 'firstly in a pan dry roast 1 cup sesame on low flame till it splutters.\nnow in another kadai heat 1 tsp ghee and add 1 cup jaggery.\nkeep stirring on medium flame till the jaggery melts completely. alternatively, use sugar, if you do not prefer jaggery.\nboil the jaggery syrup on low flame till the syrup turns glossy and thickens.\ncheck the consistency, by dropping syrup into a bowl of water, it should form hard ball and cut with a snap sound. else boil for another minute and check.\nsimmer the flame add add roasted sesame seeds.\nstir well making sure jaggery syrup coats well.\nimmediately pour the mixture over butter paper or onto steel plate greased with ghee. be quick else the mixture turns hard and will be difficult to set.\nget together forming a block, be careful as the mixture will be very hot.\nnow using a rolling pin roll the slightly thick block.\nallow to cool for a minute, and when its still warm cut into pieces.\nlastly, serve til chikki once cooled completely, or store in a airtight container and serve for a month.', 'instructions_list': ['firstly in a pan dry roast 1 cup sesame on low flame till it splutters.', 'now in another kadai heat 1 tsp ghee and add 1 cup jaggery.', 'keep stirring on medium flame till the jaggery melts completely. alternatively, use sugar, if you do not prefer jaggery.', 'boil the jaggery syrup on low flame till the syrup turns glossy and thickens.', 'check the consistency, by dropping syrup into a bowl of water, it should form hard ball and cut with a snap sound. else boil for another minute and check.', 'simmer the flame add add roasted sesame seeds.', 'stir well making sure jaggery syrup coats well.', 'immediately pour the mixture over butter paper or onto steel plate greased with ghee. be quick else the mixture turns hard and will be difficult to set.', 'get together forming a block, be careful as the mixture will be very hot.', 'now using a rolling pin roll the slightly thick block.', 'allow to cool for a minute, and when its still warm cut into pieces.', 'lastly, serve til chikki once cooled completely, or store in a airtight container and serve for a month.'], 'language': 'en-US', 'nutrients': {}, 'prep_time': 5, 'ratings': 5.0, 'ratings_count': 196, 'site_name': "Hebbar's Kitchen", 'title': 'til chikki recipe | sesame chikki recipe | til ki chikki or til gajak', 'total_time': 15, 'yields': '24 servings'}
"""

# Dump the JSON with proper formatting
formatted_json = ast.literal_eval(json_string)

print(formatted_json)

Ошибка, которую я получаю

  File <unknown>:2
    {'author': 'Hebbars Kitchen', 'canonical_url': 'https://hebbarskitchen.com/til-chikki-recipe-sesame-chikki-gajak/', 'category': 'sweet', 'cook_time': 10, 'cuisine': 'Indian', 'description': 'easy til chikki recipe | sesame chikki recipe | til ki chikki or til gajak', 'host': 'hebbarskitchen.com', 'image': 'https://hebbarskitchen.com/wp-content/uploads/mainPhotos/til-chikki-recipe-sesame-chikki-recipe-til-ki-chikki-or-til-gajak-2.jpeg', 'ingredient_groups': [{'ingredients': ['1 cup sesame / til (white)', '1 tsp ghee / clarified butter', '1 cup jaggery / gud'], 'purpose': None}], 'ingredients': ['1 cup sesame / til (white)', '1 tsp ghee / clarified butter', '1 cup jaggery / gud'], 'instructions': 'firstly in a pan dry roast 1 cup sesame on low flame till it splutters.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ^
SyntaxError: unterminated string literal (detected at line 2)

Заменить ' на "?

Marc 24.08.2024 15:00
ast.literal_eval должно было сработать. Пожалуйста, покажите нам точный код, который вы пробовали.
John Gordon 24.08.2024 15:14

@JohnGordon Эта строка не представляет ничего, что можно было бы преобразовать ни в JSON, ни в словарь Python, поскольку существует незавершенный строковый литерал. Это вызвано встроенными символами новой строки.

SIGHUP 24.08.2024 15:19

@MarkTolonen Как извлечь необработанную строку Python из базы данных?

SIGHUP 24.08.2024 15:36

@MarkTolonen Конечно, но это всего лишь MRE. Четко указано, что данные поступают из базы данных. Согласен, что показанный код можно просто изменить, чтобы указать необработанную строку, но я не думаю, что это действительно важно.

SIGHUP 24.08.2024 15:38
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
5
59
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуйте это

  import ast
  import json

  # Correct the string to properly use triple quotes
  json_string = """{'author': 'Hebbars Kitchen'}"""

  try:
  # Step 1: Parse the string into a Python dictionary
  data = ast.literal_eval(json_string)

  # Step 2: Serialize the dictionary into a valid JSON string
  valid_json = json.dumps(data)

  # Step 3: Print or update the database with `valid_json`
  print(valid_json)

  # Save to database.....
 
  except (ValueError, SyntaxError) as e:
     print("Error parsing the string:", e)

Использование ast.literal_eval()

Безопасность: ast.literal_eval() оценивает только те литералы и выражения, которые безопасны и обычно встречаются в таких форматах данных, как JSON (например, строки, числа, списки, словари).

Безопасность. Использование eval() для ненадежных входных данных может быть опасным, поскольку может выполнить произвольный код. ast.literal_eval() позволяет избежать этого риска, ограничивая типы выражений, которые он может оценивать.

пожалуйста, попробуйте всю строку, которую этот код выдаст ошибку.

Rasik 24.08.2024 15:24

Это работает, но подход @SIGHUP лучше, я попробовал здесь - programiz.com/online-compiler/3ZzYlmgedcnpO

Deeku 24.08.2024 15:40
Ответ принят как подходящий

Встроенные символы новой строки приведут к сбою literal_eval.

Вы можете просто удалить их и получить желаемый результат следующим образом:

import ast
import json
d = ast.literal_eval(json_string.replace("\n", "")
print(json.dumps(d, indent=2))

Таким образом, d будет относиться к действительному словарю Python.

когда я печатаю d, он все равно печатается с одинарными кавычками.

Rasik 24.08.2024 15:31

@Расик Да. Это потому, что это словарь Python. Используйте json.dumps() для представления JSON. Я предполагал, что ты знаешь, как это сделать. Я улучшу свой ответ

SIGHUP 24.08.2024 15:33

Почему бы не заменить \n на \\n, чтобы сохранить исходное форматирование?

Mark Tolonen 24.08.2024 15:39

@MarkTolonen Потому что это не решает проблему. Если json_string не является необработанной строкой, то замена «\n» на «\\n» приведет к сбою literal_eval.

SIGHUP 24.08.2024 15:40

А, это потому, что строка в тройных кавычках начинается и заканчивается символом новой строки. Однако это может быть артефактом примера со строкой. Если бы это было """{'author'...'24 servers'}""", это сработало бы. или json_string.strip().replace('\n', '\\n').

Mark Tolonen 24.08.2024 15:48

Чтобы исправить строку типа JSON с одинарными кавычками и преобразовать ее в действительный формат JSON:

Сначала замените одинарные кавычки двойными. Используйте str.replace(), чтобы заменить одинарные кавычки на двойные.

Затем подтвердите результат. Используйте json.loads(), чтобы проверить, является ли строка допустимым JSON.

Вот краткий пример:

import json

# Original string with single quotes
json_string = "{'key': 'value'}"

# Replace single quotes with double quotes
valid_json_string = json_string.replace("'", '"')

# Validate and format the JSON
try:
    json_data = json.loads(valid_json_string)
    formatted_json = json.dumps(json_data, indent=4)
    print(formatted_json)
except json.JSONDecodeError as e:
    print(f"JSON decoding failed: {e}")

В этом примере кода одинарные кавычки заменяются двойными, а затем выполняется попытка анализа JSON. Если синтаксический анализ успешен, он печатает отформатированный JSON. Если возникает проблема, он обнаруживает ошибку и печатает сообщение об ошибке.

Другие вопросы по теме