Как получить данные из сериализованной строки при помощи Python?

Есть данные подобного вида, полученные от БД:

[('a:5:{s:4:"NAME";s:10:"Агния";s:9:"LAST_NAME";s:0:"";s:5:"EMAIL";s:41:"[email protected]";s:4:"CODE";s:4:"5433";s:7:"MESSAGE";s:77:"Вы запросили ваши регистрационные данные.";}',), ('a:5:
{s:4:"NAME";s:12:"Демьян";s:9:"LAST_NAME";s:0:"";s:5:"EMAIL";s:41:"[email protected]";s:4:"CODE";s:4:"1968";s:7:"MESSAGE";s:77:"Вы запросили ваши регистрационные данные.";}',),  ('a:5:{s:4:"NAME";s:10:"Раиля";s:9:"LAST_NAME";s:0:"";s:5:"EMAIL";s:41:"[email protected]";s:4:"CODE";s:4:"6745";s:7:"MESSAGE";s:77:"Вы запросили ваши регистрационные данные.";}',)]

Насколько понял, это сериализованная строка. Как мне получить данные полей EMAIL и CODE с использованием python?


Ответы (1 шт):

Автор решения: DiMithras

Это не сериализованная строка, а чёрти что. У сериализации должны быть правила, а тут ну очень много :, что не под одну разметку не ложится. К формату надо приводить, чтобы десериализовать.

Но не будем о грустном, вопрос был в том как достать данные, и нет ничего невозможного для :

import re
from pprint import pprint

s = # сюда ту ебурдень, что Вы выложили в вопросе.

terms = ['EMAIL', 'CODE']
result = {term: [] for term in terms}
for i in s:
    for term in terms:
        pattern = r'"('+term+r')"[^"]+"([^"]+)'
        result[re.search(pattern, i[0]).group(1)].append(re.search(pattern, i[0]).group(2))
pprint(result)
Вывод:
{'CODE': ['5433', '1968', '6745'],
 'EMAIL': ['[email protected]',
           '[email protected]',
           '[email protected]']}

Парсинг всей строки

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

Вариант 1

temp = re.sub(r'[a-z]:\d+:', r'', str(s))
temp = re.sub(r';(.*?);', r':\1,', temp)
temp = re.sub(r',}', r'}', temp)
temp = re.sub(r"\(\'|\),|\|,'|\'|,\)", r'', temp)
json.loads(temp)
[{'NAME': 'Агния',
  'LAST_NAME': '',
  'EMAIL': '[email protected]',
  'CODE': '5433',
  'MESSAGE': 'Вы запросили ваши регистрационные данные.'},
 {'NAME': 'Демьян',
  'LAST_NAME': '',
  'EMAIL': '[email protected]',
  'CODE': '1968',
  'MESSAGE': 'Вы запросили ваши регистрационные данные.'},
 {'NAME': 'Раиля',
  'LAST_NAME': '',
  'EMAIL': '[email protected]',
  'CODE': '6745',
  'MESSAGE': 'Вы запросили ваши регистрационные данные.'}]

Вариант 2

⚠ С eval() надо быть очень осторожным.

temp = re.sub(r'([a-z]:\d+)', r'"\1"', str(s))
temp = re.sub(r'(?<=");', ',', temp)
temp = re.sub(r',}', r'}', temp)
temp = re.sub(r"\(\'|\),|\|,'|\'|,\)", r'', temp)
temp = re.sub(r"(\[|,\s)", r'\1{', temp)
temp = re.sub(r"(\]|,\s)", r'}\1', temp)
eval(temp)
[{'a-5': {'s-4': '5433',
   's-10': 'Агния',
   's-9': 'LAST_NAME',
   's-0': '',
   's-5': 'EMAIL',
   's-41': '[email protected]',
   's-7': 'MESSAGE',
   's-77': 'Вы запросили ваши регистрационные данные.'}},
 {'a-5': {'s-4': '1968',
   's-12': 'Демьян',
   's-9': 'LAST_NAME',
   's-0': '',
   's-5': 'EMAIL',
   's-41': '[email protected]',
   's-7': 'MESSAGE',
   's-77': 'Вы запросили ваши регистрационные данные.'}},
 {'a-5': {'s-4': '6745',
   's-10': 'Раиля',
   's-9': 'LAST_NAME',
   's-0': '',
   's-5': 'EMAIL',
   's-41': '[email protected]',
   's-7': 'MESSAGE',
   's-77': 'Вы запросили ваши регистрационные данные.'}}]
→ Ссылка