Преобразование строки в имена и значения хранимых переменных (как строки, так и объекты) - PullRequest
1 голос
/ 28 июня 2011

2015 Редактировать Не делайте этого.Будьте хорошим человеком и просто используйте JSON.parse():)

Я пытаюсь взять строку, содержащую переменные и значения в подобном javascript-синтаксисе, и сохранить их в глобальном объекте (gv).Моя проблема только с разбором строки.

String (все внутри <div>):

<div id="gv">       
    variableName = "variableValue,NoSpacesThough";
    portal = "TheCakeIsALie";
</div>

Script (разбирает строку выше, помещает значения в глобальный объект) :

var s = (document.getElementById("gv").innerHTML).split(';');
for (var i = 0; i < s.length; i++) {
    if (s[i] !== "\n" || "") {
        s[i] = s[i].replace(/^\s*/gm, "");
        var varName = s[i].substr(0, s[i].indexOf('=') - 1),
            varValue = (s[i].substr((s[i].indexOf('"') + 1), s[i].length)).replace('"', "");
        gv[varName] = varValue;
    }
}

Результат:

console.log(gv.variableName); //returns: variableValue,NoSpacesThough
console.log(gv.portal); //returns: TheCakeIsALie

В: Как правильно изменить этот скриптсохранить эти переменные:

exampleVariable = { name: "string with spaces", cake:lie };
variableName = "variableValue,NoSpacesThough";    
portal = "The Cake Is A Lie";

Прямо выше есть объект, содержащий: Строка с пробелами (и "), ссылка

Спасибо.

1 Ответ

3 голосов
/ 28 июня 2011

Четыре варианта / мысли / предложения:

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"
}

Как видите, единственные отличия:

  1. Вы заверните все это в фигурные скобки ({}).
  2. Вы помещаете «переменные» имена (имена свойств) в двойные кавычки.
  3. Вы используете двоеточие, а не знак равенства после имени свойства.
  4. Вы используете запятую, а не точку с запятой для разделения свойств (так же, как в литерале объекта, который имеется в строке exampleVariable).
  5. Вы гарантируете, что любые строковые значения используют двойные, а не одинарные кавычки (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 из строки. Но поскольку он запускает любой код, который вы ему дадите, это не хороший выбор для десериализации подобных вещей, и любые свободные переменные (например, те, которые вы цитировали) в конечном итоге будут глобальными. На самом деле очень некрасиво, я в основном упоминаю это, чтобы сказать: не используйте это. : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...