Самый простой способ приблизиться к этому - заметить, что есть два вложенных уровня, которые работают одинаково. Шаблон очень прост:
id^length^content^
На внешнем уровне это создает набор групп. Внутри каждой группы content
следует точно так же, только здесь id
- это имя переменной, а content
- это значение переменной.
Так что вам нужно написать эту логику только один раз, и вы можете использовать ее для анализа обоих уровней. Просто напишите функцию, которая разбивает строку на список пар id
/ content
. Вызовите его один раз, чтобы получить группы, а затем выполните цикл, вызывая его снова для каждого content
, чтобы получить переменные в этой группе.
Разбивая его на эти шаги, сначала нам нужен способ получить «токены» из строки. Эта функция возвращает объект с тремя методами, чтобы узнать, находимся ли мы в «конце файла», и захватить следующую разделенную или подсчитанную подстроку:
var tokens = function(str) {
var pos = 0;
return {
eof: function() {
return pos == str.length;
},
delimited: function(d) {
var end = str.indexOf(d, pos);
if (end == -1) {
throw new Error('Expected delimiter');
}
var result = str.substr(pos, end - pos);
pos = end + d.length;
return result;
},
counted: function(c) {
var result = str.substr(pos, c);
pos += c;
return result;
}
};
};
Теперь мы можем удобно написать повторно используемую функцию разбора:
var parse = function(str) {
var parts = {};
var t = tokens(str);
while (!t.eof()) {
var id = t.delimited('^');
var len = t.delimited('^');
var content = t.counted(parseInt(len, 10));
var end = t.counted(1);
if (end !== '^') {
throw new Error('Expected ^ after counted string, instead found: ' + end);
}
parts[id] = content;
}
return parts;
};
Он создает объект, в котором ключами являются идентификаторы (или имена переменных). Я предполагаю, поскольку у них есть имена, что порядок не имеет значения.
Затем мы можем использовать это на обоих уровнях для создания функции, выполняющей всю работу:
var parseGroups = function(str) {
var groups = parse(str);
Object.keys(groups).forEach(function(id) {
groups[id] = parse(groups[id]);
});
return groups;
}
Для вашего примера, он производит этот объект:
{
'1': {
VAR1: 'VALUE1'
},
'4': {
VAR1: 'VALUE1',
VAR2: 'VAL2'
}
}