C ++: анализ строки JSON с ключами, не заключенными в двойные кавычки

В течение некоторого времени я успешно использую библиотеку Cabablanca Json C ++ (cpprest). Свой парсер (web::json::value::parse(<json_string>)) отлично работает на действительный Строки JSON. Скажите, что это будет правильно проанализировано:

{
"key1": [["1", 0.4], ["0", 0.6]],
"key2": true,
"key3": 1,
"key4": [{"key41": 1}, {"key42": [1,2,3]}]
}

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

{
key1: [[1, 0.4], [0, 0.6]],
key2: true,
key3: 1,
key4: [{key41: 1}, {key42: [1,2,3]}]
}

Есть хороший способ правильно проанализировать это и затем сериализовать в действительный JSON, чтобы Casablanca мог правильно проанализировать результирующий действительный JSON?

Hjson Кажется, работает для этой цели, но он не обеспечивает необходимую библиотеку для C ++. Они упоминают jzon библиотека для C — я попробовал: она имеет только односторонний синтаксический анализ (без сериализации), и даже синтаксический анализ не работает правильно (не может даже проанализировать допустимые JSON)

0

Решение

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

То, что у вас есть, это javascript-подобный объект. Давайте подключим его к движку javascript и используем его, чтобы выплевывать правильный JSON. Я буду использовать Qt’s QJSEngine так как я сносно знаком с этим:

constexpr char const* str = R"({
key1: [[1, 0.4], [0, 0.6]],
key2: true,
key3: 1,
key4: [{key41: 1}, {key42: [1,2,3]}]
})";

QJSEngine e;

QString script = QString("JSON.stringify(%0)").arg(str);

тогда вы можете просто оценить это:

e.evaluate(script).toString().toStdString()

доходность

{"key1":[[1,0.4],[0,0.6]],"key2":true,"key3":1,"key4":[{"key41":1},{"key42":[1,2,3]}]}
1

Другие решения

Этот грубый метод будет работать.

(Непроверенный код)

У нас есть три состояния, НЕЙТРАЛЬНЫЕ, ONSTRING и ONALNUM.

Мы начинаем в НЕЙТРАЛЬНО. Если мы нажимаем » ‘, мы переходим в ONSTRING. Если мы нажимаем альфа, мы переходим в ONALNUM. Если мы входим или выходим из alnum, мы выдаем кавычку. Мы также испускаем прочитанный символ.
Если мы находимся в ONALNUM, мы выходим из него, когда нажимаем non-alnum, и переходим в NEUTRAL, если только мы не нажимаем quote, когда это ошибка синтаксического анализа. Если мы находимся в ONSTRING, мы применяем правила экранирования строки JSON, которые я не знаю, неявно.

 #define NEUTRAL 0
#define ONSTRING 1
#define ONALNUM 2

int state = NEUTRAL;
char *inptr = str;
char ch;

while( (ch = *inptr++))
{
if(state == NEUTRAL)
{
if( isalpha(ch) )
{
emit('\"');
state = ONALNUM;
}
else if(ch = '\"')
state = ONSTRING;
emit(ch);
}
else if(state == ONSTRING)
{
/* JSON string escape rules here */
if(ch == '\"')
state = NEUTRAL;
emit(ch);
}
else if(state == ONALNUM)
{
emit(ch);
if(!isalnum(ch))
{
state = NEUTRAL;
emit('\"');
}
}
}
0

проблема

В контексте вашего вопроса вам кажется, что вы хотите удалить «», чтобы иметь правильный формат JSON.

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

Решение

Для этого мы будем использовать std::replace функция от <algorithm> библиотека; хотя мы можем реализовать это самостоятельно, лучше использовать стандартные библиотеки, так как создатели их усердно работали над оптимизацией этих функций в полном объеме. Итак, давайте возьмем ваш код, который вы дали нам из вопроса, и сделаем его соответствующим JSON.

#include <algorithm>
#include <string>
#include <iostream>

using std::string;
using std::cout;
using std::endl;

void convert_char(string &s,char from_conv, char to_conv) {
std::replace( s.begin(), s.end(), from_conv, to_conv); // replace all 'x' to 'y'
}

int main()
{
string str =  "{ \n \
\"key1\": [[\"1\", 0.4], [\"0\", 0.6]], \n \
\"key2\": true, \n \
\"key3\": 1,  \n \
\"key4\": [{\"key41\": 1}, {\"key42\": [1,2,3]}] \n }";;
convert_char(str,'\"',(char)0);
cout << str << endl;
}

Вы можете увидеть здесь у нас есть функция под названием convert_char который преобразует определенный символ в другой. Таким образом, в основном, как ваш вопрос, мы удалили двойную кавычку, и тада, она отформатирована как JSON! Взглянуть Вот для демо.

Решение для JSON Parser

Очевидно, что здесь вы будете использовать библиотеку, чтобы сделать это для вас. Я собираюсь представить sciter тебе! В основном, с sciter все, что вам нужно сделать, это:

#include <algorithm>
#include <string>
#include <iostream>
#include <sciter>

using std::string;
using std::cout;
using std::endl;

int main()
{
string str =  "{ \n \
\"key1\": [[\"1\", 0.4], [\"0\", 0.6]], \n \
\"key2\": true, \n \
\"key3\": 1,  \n \
\"key4\": [{\"key41\": 1}, {\"key42\": [1,2,3]}] \n }";;
sciter::value str_conv = sciter::value::from_string( str, CVT_JSON_LITERAL );
cout << str_conv << endl;
}

Теперь в соответствии с этим кодом форматированный код JSON находится в str_conv! Ссылки, которые помогут вам в этом, приведены ниже в разделе «Ссылки».

Рекомендации:

sciter

cpprefrence std::replace

string::replace

cpprefrence std::refrence_if

глоссарий

std::replace :

Прототип:

template <class ForwardIterator, class T>
void replace (ForwardIterator first, ForwardIterator last,
const T& old_value, const T& new_value); //source cpprefrence

Рекомендации: cpprefrence

<algorithm>:

Многие темы находятся внутри библиотеки алгоритмов. Это библиотека для, как вы уже догадались, алгоритмов.

Заголовок <algorithm> определяет набор функций, специально предназначенных для использования в диапазонах элементов.

Диапазон — это любая последовательность объектов, к которой можно получить доступ через итераторы или указатели, такие как массив или экземпляр некоторых контейнеров STL. Обратите внимание, что algorithms работать через iterators непосредственно на значениях, не влияет каким-либо образом структура любого возможного контейнера (это никогда не влияет на размер или распределение хранилища контейнера).

Библиотека алгоритмов определяет функции для различных целей (например, поиск, сортировка, подсчет, манипулирование), которые работают с диапазонами элементов.

Рекомендации:

cplusplus

cpprefrence

-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector