Qt Разбор пользовательского формата файла

avatar
Nicholas Johnson
7 апреля 2018 в 23:26
255
1
1

У меня есть куча пользовательских скриптов, формат файлов которых похож, но отличается от JSON. Я хотел бы взять эти файлы и передать их данные в QTreeWidget и отобразить необработанный код с некоторой подсветкой синтаксиса. Мне не нужно выполнять эти задачи, мне просто нужен чистый способ или идея о том, как я могу извлечь из них информацию. Вот пример фрагмента скрипта.

Пример:

"People"
{
    "Person 1"
    {
        "age"       "34"
        "name"      "John"
        "gender"    "male"
        "skills"
        {
            "skill 1"   "Intelligent"
            "skill 2"   "Wise"
            "skill 3"   "Buff as a bear!"
        }
    }
    "Person 2"
    {
        "age"       "25"
        "name"      "Jamie"
        "gender"    "helicopter"
    }
}
Источник
Hải Phạm Lê
7 апреля 2018 в 23:54
0

Может быть, вам нужна переменная «заглянуть вперед»? который будет читать следующий токен, пока вы обрабатываете текущий, поэтому вы можете решить, что текущий является полем его родителя или именем вложенной структуры.

MrEricSir
8 апреля 2018 в 02:14
0

Этот формат выглядит как контекстно-свободная грамматика; вам понадобится стек для его анализа. Возможно, вы сможете настроить существующую библиотеку JSON для чтения формата.

Nicholas Johnson
8 апреля 2018 в 02:16
0

@MrEricSir Я имею в виду, что все, что мне нужно сделать, это добавить двоеточие, запятые и несколько квадратных скобок, и бум, это JSON. Просто такая боль с RegExp

MrEricSir
8 апреля 2018 в 03:03
1

@NicholasJohnson Забудьте об использовании регулярных выражений в этом случае, потому что вы имеете дело не с обычной грамматикой. Это слишком сложно для комментария Stack Overflow, но иерархия Хомского объясняет различие.

Kuba hasn't forgotten Monica
9 апреля 2018 в 17:44
0

Самое простое решение — довольно тривиальное, поскольку изменения составляют всего несколько строк — это скопировать реализацию Qt Json и настроить ее для работы с вашим синтаксисом. У вас есть исходники Qt. Используй их!

Ответы (1)

avatar
wp78de
8 апреля 2018 в 05:08
0

Я попытался немного поиграться с регулярными выражениями в C++ 11/14. Но, честно говоря, это не забавная проблема, и регулярное выражение, вероятно, не подходит для этой работы.

Я придумал этот код, который преобразует ваш образец ввода в действительный JSON:

#include <iostream>
#include <regex>
using namespace std;    
int main (int argc, const char * argv[]) {
std::string test = R"(
"People"
{
    "Person 1"
    {
        "age"       "34"
        "name"      "John"
        "gender"    "male"
        "skills"
        {
            "skill 1"   "Intelligent"
            "skill 2"   "Wise"
            "skill 3"   "Buff as a bear!"
        }
    }
    "Person 2"
    {
        "age"       "25"
        "name"      "Jamie"
        "gender"    "helicopter"
    }
}
)";
    regex reg(R"(("[^"]+")\s+("[^"]+"))");
    test = std::regex_replace(test, reg, "$1:$2,");
    regex reg2(R"((?:\A|\n)\s*("[^"]+")\s*(\n|\Z))");
    test = std::regex_replace(test, reg2, "$1:");
    regex reg3(R"(}\s*("[^"]+"):\s*\{)");
    test = std::regex_replace(test, reg3, "},\n$1: {");
    regex reg4(R"(,\s*})");
    test = std::regex_replace(test, reg4, "}");
    cout << "{" << test << "}" << endl;
}

Вывод:

{"People":{"Person 1":    {
        "age":"34",
        "name":"John",
        "gender":"male","skills":        {
            "skill 1":"Intelligent",
            "skill 2":"Wise",
            "skill 3":"Buff as a bear!"}
    },
"Person 2": {
        "age":"25",
        "name":"Jamie",
        "gender":"helicopter"}
}
}

Демо

Однако ваш пробег может варьироваться в зависимости от других, более сложных входных данных.