Четыре варианта / мысли / предложения:
1. Используйте JSON
Если вы контролируете исходный формат, я бы порекомендовал использовать JSON , а не свой собственный. Подробности на этой странице. JSON теперь является частью ECMAScript (JavaScript) стандарта со стандартными методами создания строк JSON из графов объектов и наоборот. С вашим примером:
exampleVariable = { name: "string with spaces", cake:lie };
variableName = "variableValue,NoSpacesThough";
portal = "The Cake Is A Lie";
вот как будет выглядеть JSON-эквивалент:
{
"exampleVariable": { name: "string with spaces", cake:lie },
"variableName": "variableValue,NoSpacesThough",
"portal": "The Cake Is A Lie"
}
Как видите, единственные отличия:
- Вы заверните все это в фигурные скобки (
{}
).
- Вы помещаете «переменные» имена (имена свойств) в двойные кавычки.
- Вы используете двоеточие, а не знак равенства после имени свойства.
- Вы используете запятую, а не точку с запятой для разделения свойств (так же, как в литерале объекта, который имеется в строке
exampleVariable
).
- Вы гарантируете, что любые строковые значения используют двойные, а не одинарные кавычки (JavaScript допускает и то, и JSON более строгие). В вашем примере используются двойные кавычки, но я упоминаю об этом на всякий случай ...
2. Предварительно обработайте его в JSON с помощью регулярных выражений
Если вы не контролируете исходный формат, но он точно , как вы показали, вы можете довольно легко переформатировать его в JSON с помощью регулярных выражений, а затем десериализовать его с помощью JSON , Но если формат более сложный, чем вы указали, он очень быстро начинает волосать.
Вот пример ( живая копия ) преобразования того, что вы цитировали в JSON:
function transformToJSON(str) {
var rexSplit = /\r?\n/g,
rexTransform = /^\s*([a-zA-Z0-9_]+)\s*=\s*(.+);\s*$/g,
rexAllWhite = /\s+/g,
lines,
index,
line;
lines = str.split(rexSplit);
index = 0;
while (index < lines.length) {
line = lines[index];
if (line.replace(rexAllWhite, '').length === 0) {
// Blank line, remove it
lines.splice(index, 1);
}
else {
// Transform it
lines[index] = line.replace(rexTransform, '"$1": $2');
++index;
}
}
result = "{\n" + lines.join(",\n") + "\n}";
return result;
}
... но будьте осторожны , поскольку, опять же, формат основан на том, что вы указали, и, в частности, он основан на том, что каждое значение в одной строке и любые строковые значения в двойных кавычках (требование JSON). Вам, вероятно, придется обрабатывать сложности, которые вышеупомянутые не обрабатывают, но вы не можете сделать это с такими вещами, как ваша первая строка var s = (document.getElementById("gv").innerHTML).split(';');
, которая разбивает строки на ;
независимо от того, находится ли ;
в кавычках ...
3. На самом деле проанализируйте его, изменив синтаксический анализатор JSON для поддержки вашего формата
Если вы не можете изменить формат и он менее точен, чем приведенные вами примеры, вам придется приступить к фактическому анализу; нет ярлыков (ну, нет надежных ). На самом деле синтаксический анализ литералов JavaScript (я предполагаю, что в ваших данных нет выражений , кроме выражения присваивания, конечно) не так уж плох. Вы могли бы, вероятно, взять анализатор JSON и изменить его под свои нужды, поскольку он уже будет иметь почти всю логику для литералов. На странице github Крокфорда есть два (Крокфорд является изобретателем JSON), один с использованием рекурсивного спуска и другой с использованием конечного автомата . Сделайте свой выбор и начните взламывать.
4. Зло eval
Полагаю, мне следует упомянуть eval
здесь, хотя я не рекомендую вам его использовать. eval
запускает произвольный код JavaScript из строки. Но поскольку он запускает любой код, который вы ему дадите, это не хороший выбор для десериализации подобных вещей, и любые свободные переменные (например, те, которые вы цитировали) в конечном итоге будут глобальными. На самом деле очень некрасиво, я в основном упоминаю это, чтобы сказать: не используйте это. : -)