2016-07-26 2 views
2

Я знаю, как разобрать действительную строку JSON: JSON.parse('{"key" : "value"}').JS: как преобразовать строку в объект JS (** NOT ** в JSON)?

Но как насчет действительный объект JS, но недействительный JSON, например: JSON.parse("{ key : 'value'}")? В приведенном выше примере броски:

Uncaught SyntaxError: Unexpected token k in JSON at position 2

Моя текущая цель еще сложнее. Я хочу, чтобы разобрать строку объекта JS содержащий RegEx (неподдерживаемый на JSON, но поддерживаемый JS) в объект JS:

'{ key1 : /val1/g , key2 : /val2/i }' 

В конце концов я хочу использовать этот объект с Мангуста и найти документы с ним:

Model.find({ 
    key1 : /val1/g , 
    key2 : /val2/i 
}) 

Я пытался применять довольно сложные регулярные выражения моей строки, заменяя /val1/g с new RegEx("val1","i"):

str = str.replace(/\/(.+?)\/(g?i?).+?(?=,|})/g , "new RegExp(`$1`,`$2`)") 

Операция .replace() работает и изменяет строку так, как я ее хочу. Это дает:

{ key1 : new RegExp("val1","g") , key2 : new RegExp("val2","i") } 

Но когда я пытаюсь применить JSON.parse к нему, он по-прежнему не удается, потому что new RegEx("val1","i") не является допустимым значением.

+4

Я ненавижу себя за это, но, возможно, 'eval' - это то, что вы ищете? –

+0

Спасибо, я действительно об этом не думал. Eval слишком мощный :) –

ответ

9

Если вы контролируете и можете доверять текст вы преобразовывая, вы можете использовать eval:

var str = '{ key1 : /val1/g , key2 : /val2/i }'; 
 
var obj = eval("(" + str + ")"); 
 
console.log(obj.key1);

Обратите внимание, что при выполнении eval, так как ваше выражение начинается с {, вы должны обернуть его в (), чтобы анализатор знал, что начинается инициализатор объекта, а не блок.

Несколько замечаний о eval:

  1. Это позволяет выполнить произвольный код. Таким образом, вам действительно нужно доверять тексту, который вы используете eval ing. Не вводите пользователя eval.

  2. Код в контексте выполнения, непосредственно содержащий вызов eval, в принципе не может быть оптимизирован, поскольку механизм JavaScript не может знать при анализе кода то, что будет содержать строка. Поэтому, хотя я предполагаю, что технически это преждевременная оптимизация, я бы убрал вышеприведенную функцию, которую вы вызываете из своей основной логики, а не напрямую встраиваете ее в свою основную логику.

+1

Это большой «если» ;-) –

+0

Кроме того, я думаю, что это предотвратит оптимизацию JIT. –

+1

@JoachimSauer: Да, я попытался отметить его довольно большим. :-) Вопрос подсказывает, что это может быть так. –

Смежные вопросы