Я пробовал кое-что с модулем pyparsing, чтобы получить некоторое представление об общем анализе.
Мне дали вопрос для интервью (который был отправлен, поэтому я не думаю, что сейчас есть какие-либо этические проблемы), чтобы обработать структуру данных, подобную приведенной ниже, из текстового файла.
Collection Top_Level_Collection "Junk1"
{
Column Date_time_column 1 {"01-21-2011"}
Collection Pig_Entry "Sammy"
{
Column Animal_locations 35 {"Australia", "England", "U.S."}
Data 4
{
4 0 72033 Teeth 2 {1 "2", 1 "3"};
1 0 36331 Teeth 2 {2 "2", 3 "4"};
2 3 52535 Teeth 2 {6 "4", 9 "3"};
4 0 62838 Teeth 2 {3 "7", 7 "6"};
}
}
}
Я могу получить действительно хакерское решение с регулярным выражением и подсчетом столбцов, чтобы извлекать фрагменты данных и объединять их, но я хотел бы расширить свои знания в синтаксическом анализе, чтобы делать вещи более красноречиво.
Видно, что базовая структура сначала является «Основной абстрактный тип данных», затем следует необязательный «конкретный тип данных», затем либо «имя», либо «количество записей», при этом он может быть бесконечно вложенным.
Вот что я получил до сих пор, пытаясь разобрать словарь:
import numpy as np
import pyparsing as pp
test_str = '''
Collection Top_Level_Collection "Junk"
{
Column Date_time_column 1 {"01-21-2011"}
Collection Pig_Entry "Sammy"
{
Column Animal_locations 35 {"Australia", "England", "U.S."}
Data 4
{
4 0 72033 Teeth 2 {1 "2", 1 "3"};
1 0 36331 Teeth 2 {2 "2", 3 "4"};
2 3 52535 Teeth 2 {6 "4", 9 "3"};
4 0 62838 Teeth 2 {3 "7", 7 "6"};
}
}
}
'''
if __name__ == '__main__':
expr = pp.Forward()
object_type = pp.Word( pp.alphanums + '_')
object_ident = pp.Word( pp.alphanums + '_')
object_name_or_data_num = pp.Word( pp.alphanums + '_".')
ident_group = pp.Group(object_type + pp.Optional(object_ident) + object_name_or_data_num)
nestedItems = pp.nestedExpr("{", "}")
expr << pp.Dict(ident_group + nestedItems)
all_data_dict = (expr).parseString(test_str).asDict()
print all_data_dict
print all_data_dict.keys()
который возвращает:
{'Column': (['Date_time_column', '1', (['"01-21-2011"'], {}), 'Collection', 'Pig_Entry', '"Sammy"', (['Column', 'Animal_locations', '35', (['"Australia"', ',', '"England"', ',', '"U.S."'], {}), 'Data', '4', (['4', '0', '72033', 'Teeth', '2', (['1', '"2"', ',', '1', '"3"'], {}), ';', '1', '0', '36331', 'Teeth', '2', (['2', '"2"', ',', '3', '"4"'], {}), ';', '2', '3', '52535', 'Teeth', '2', (['6', '"4"', ',', '9', '"3"'], {}), ';', '4', '0', '62838', 'Teeth', '2', (['3', '"7"', ',', '7', '"6"'], {}), ';'], {})], {})], {}), 'Collection': (['Top_Level_Collection', '"Junk"'], {})}
['Column', 'Collection']
Однако я надеюсь, что он вернет что-то, что можно легко отправить в классы Python для создания объектов. Мое лучшее предположение для этого - поместить их во вложенный словарь, где ключ представляет собой кортеж из 2 или 3 типов объектов, а значение представляет собой словарь с каждым значением ключа под ним. т.е. Что-то похожее на это:
{ (Collection, Top_Level_Collection, "Junk1"):
{ (Column, Date_time_column): ["01-21-2011"],
(Collection, Pig_Entry, "Sammy"):
{ (Column, Animal_locations): ["Australia", "England", "U.S."],
(Data): [[ 4 0 72033 {(Teeth):[1 "2", 1 "3"]} ]
[ 1 0 36331 {(Teeth):[2 "2", 3 "4"]} ]
[ 2 3 52535 {(Teeth):[6 "4", 9 "3"]} ]
[ 4 0 62838 {(Teeth):[3 "7", 7 "6"]} ]]
}
}
}