【问题标题】:JS : how to convert a string to JS Object (**NOT** to JSON)?JS:如何将字符串转换为 JS 对象(**NOT** 为 JSON)?
【发布时间】:2016-07-26 16:09:58
【问题描述】:

我知道如何解析有效的 JSON 字符串:JSON.parse('{"key" : "value"}')

但是 有效的 JS 对象,但无效的 JSON 呢,例如:JSON.parse("{ key : 'value'}")? 上面的例子抛出:

未捕获的 SyntaxError:JSON 中位置 2 的意外标记 k

我的实际目标更加棘手。我想将一个JS对象的字符串包含RegEx(JSON不支持但JS支持)解析成一个JS对象:

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

我最终想将此对象与 Mongoose 一起使用并使用它查找文档:

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

我尝试将一个相当复杂的 RegEx 应用于我的字符串,将 /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") 不是有效值。

【问题讨论】:

  • 我讨厌自己这么说,但也许eval 是你要找的?
  • 谢谢,确实是这样,我没想到。 eval 太强大了:)

标签: javascript json string parsing object


【解决方案1】:

如果您可以控制并信任您正在转换的文本,您可以使用eval

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

请注意,在执行eval 时,由于您的表达式以{ 开头,因此您必须将其包装在() 中,以便解析器知道这是在启动对象初始化程序,而不是块。

关于eval的几点说明:

  1. 它允许执行任意代码。所以你真的必须相信你evaling 的文字。不要eval用户输入。

  2. 直接包含对eval的调用的执行上下文中的代码基本上无法优化,因为JavaScript引擎在解析代码时无法知道字符串将包含什么。因此,虽然我认为从技术上讲这是过早的优化,但我会将上述内容隐藏在您从主逻辑调用的函数中,而不是将其直接嵌入到主逻辑中。

【讨论】:

  • 这是一个很大的“如果”;-)
  • 另外,我认为它会阻止 JIT 优化。
  • @JoachimSauer:是的,我试着把它标记得相当大。 :-) 这个问题表明这里很可能就是这种情况。
  • @EmileBergeron:啊,是的,值得一提的是。我会去做的。不太可能成为问题,但仍然存在。
  • 你不是在一两周前以同样的方式回答了同样的问题吗?还是你和我一样,越来越难找到旧的问题和答案,甚至是你写的那些?
【解决方案2】:

我遇到了类似的问题,并在 split 和 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"'}

它从传递的字符串返回空对象或转换后的对象。

【讨论】:

    猜你喜欢
    • 2016-02-02
    • 2022-06-13
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 2012-05-08
    相关资源
    最近更新 更多