Cпарсить C-подобный формат на python
Нужно сделать парсер вот такого формата, как это можно сделать? Заранее спасибо!
"Users"
{
"STEAM_0:0:15256262"
{
"name" "polly"
"expires" "0"
"flags" "0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z"
}
"STEAM_0:1:24536789"
{
"name" "test_user"
"expires" "0"
"flags" "0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z"
}
}
Нужно, чтобы на выходе парсер выдавал что-то типо:
[{"steam_id": "STEAM_0:0:15256262", "name": "polly", "expires": "0", "0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z"},
{"steam_id": "STEAM_0:1:24536789", "name": "test_user", "expires": "0", "0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z"}]
Ответы (2 шт):
Автор решения: Just_a_programmer
→ Ссылка
Если первый блок это файл, информацию из которого ты хочешь спарсить, то открой файл и в строковую переменную запиши спарсенный текст.
file = open('путь к файлу', 'r')
txt = file.read()
Дальше есть строковые методы, ищешь ключевые фразы, например:
"name"
и смотришь на слова после них.
Автор решения: gil9red
→ Ссылка
Накидал простенький парсер:
- Перебираем построчно и считаем количество открывающих и закрывающих скобок
- Заполняем данные в зависимости от текущего уровня вложенности
- Для первого уровня, т.е.
steam_idдостаточно вернуть строку без первого и последнего символа - Для вытаскивания ключ-значений типа
nameиспользуется регулярное выражение"(.+?)"\s+"(.+?)", которое означает поиск в строке пары кавычек с текстом внутри ("(.+?)"), разделенными пробелами (\s+)
- Для первого уровня, т.е.
Пример:
import re
text = """\
"Users"
{
"STEAM_0:0:15256262"
{
"name" "polly"
"expires" "0"
"flags" "0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z"
}
"STEAM_0:1:24536789"
{
"name" "test_user"
"expires" "0"
"flags" "0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z"
}
}
"""
items = []
current_level = 0
for line in text.splitlines():
line = line.strip()
if line == '{':
current_level += 1
continue
elif line == '}':
current_level -= 1
continue
if current_level == 1:
steam_id = line[1:-1]
items.append({'steam_id': steam_id})
elif current_level == 2:
m = re.search(r'"(.+?)"\s+"(.+?)"', line)
key, value = m.group(1), m.group(2)
items[-1][key] = value
print(items)
Результат:
[{'steam_id': 'STEAM_0:0:15256262', 'name': 'polly', 'expires': '0', 'flags': '0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z'}, {'steam_id': 'STEAM_0:1:24536789', 'name': 'test_user', 'expires': '0', 'flags': '0a0b0c0d0h0n0p0t0w0x1b1e1f1h1k1n0z'}]
PS.
Если считывать из файла, то есть такие варианты:
Считать в переменную:
with open('путь до файла', encoding='utf-8') as f: text = f.read() ...Считывать из файла построчно:
with open('путь до файла', encoding='utf-8') as f: items = [] current_level = 0 for line in f: ...
Второй вариант особенно подходит, когда файл не влезет в память