最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JS : how to convert a string to JS Object (**NOT** to JSON)? - Stack Overflow

programmeradmin1浏览0评论

I know how to parse a valid JSON string : JSON.parse('{"key" : "value"}').

But what about a valid JS object, but invalid JSON, like : JSON.parse("{ key : 'value'}") ? The example above throws :

Uncaught SyntaxError: Unexpected token k in JSON at position 2

My actual goal is even trickier. I want to parse a string of a JS object containing RegEx (unsupported by JSON but supported by JS) into a JS object :

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

I eventually want to use this object with Mongoose and find documents with it :

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

I have tried applying a fairly plex RegEx to my String, replacing /val1/g with new RegEx("val1","i") :

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

The .replace() operation works and modifies the string the way I want it. It yields :

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

But when I try to apply JSON.parse to it, it still fails because new RegEx("val1","i")is not a valid value.

I know how to parse a valid JSON string : JSON.parse('{"key" : "value"}').

But what about a valid JS object, but invalid JSON, like : JSON.parse("{ key : 'value'}") ? The example above throws :

Uncaught SyntaxError: Unexpected token k in JSON at position 2

My actual goal is even trickier. I want to parse a string of a JS object containing RegEx (unsupported by JSON but supported by JS) into a JS object :

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

I eventually want to use this object with Mongoose and find documents with it :

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

I have tried applying a fairly plex RegEx to my String, replacing /val1/g with new RegEx("val1","i") :

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

The .replace() operation works and modifies the string the way I want it. It yields :

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

But when I try to apply JSON.parse to it, it still fails because new RegEx("val1","i")is not a valid value.

Share Improve this question edited Jul 26, 2016 at 16:12 Jeremy Thille asked Jul 26, 2016 at 16:09 Jeremy ThilleJeremy Thille 26.4k12 gold badges47 silver badges64 bronze badges 2
  • 4 I hate myself for saying this, but maybe eval is what you're looking for? – Emile Bergeron Commented Jul 26, 2016 at 16:12
  • Thanks, it is indeed, I didn't think about it. Eval is too powerful :) – Jeremy Thille Commented Jul 26, 2016 at 16:22
Add a ment  | 

2 Answers 2

Reset to default 10

If you control and can trust the text you're converting, you can use eval:

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

Note that when doing the eval, since your expression starts with {, you have to wrap it in () so the parser knows that's starting an object initializer, not a block.

A couple of notes about eval:

  1. It allows arbitrary code execution. So you really have to trust the text you're evaling. Don't eval user input.

  2. Code in an execution context directly containing a call to eval basically cannot be optimized, because the JavaScript engine can't know, when parsing the code, what the string will contain. So while I suppose technically it's premature optimization, I'd tuck the above off in a function that you call from your main logic rather than embedding it in your main logic directly.

I faced simmilar issue and solved it with the help of split and reduce.

const getObjectFromString = (stringToParse) => {
    if(typeof stringToParse === 'string'){
        let currentKey = '';
        const keyValPairArr = stringToParse.replace('{','').replace('}','').split(':');
        return keyValPairArr.reduce((obj,current,index,arr)=>{
            const previousKey = currentKey;
            const arrKeyVal = current.trim().split(',');
            currentKey = index!==arr.length-1?arrKeyVal.pop().trim():'';
            const previousVal = arrKeyVal.join(',');
            if(previousKey&&previousVal!=='')obj[previousKey]=previousVal;
            return obj;
        },{})
    }else{
        return stringToParse||{};
    }
}

// following are some results

const example1 = getObjectFromString('{first : 1, second : 2nd, third: "third, 3rd" }')
console.log(example1) // output: {first: '1', second: '2nd', third: '"third, 3rd"'}

It returns either empty object or the converted object from the passed string.

发布评论

评论列表(0)

  1. 暂无评论