【问题标题】:How to parse an string array as JSON?如何将字符串数组解析为 JSON?
【发布时间】:2017-07-12 02:06:56
【问题描述】:

我很难让这个字符串可解析。这似乎是一个简单的任务,但它让我发疯。 Infusionsoft 将此作为它们的其余钩子有效负载返回,因此我无法更改它的接收方式。

JSON.parse() 不起作用,我不能将它作为对象文字使用,因为时间戳没有引号。有没有一种方法或方式我只是看不到解析这个,所以我可以很容易地得到每个 id 用一个 for 循环作为例子?

[{id:1049105, api_url:'', timestamp: 2017-07-12T00:34:36.000Z},{id:993221, api_url:'', timestamp: 2017-07-12T00:34:18.000Z}]

任何帮助将不胜感激。

【问题讨论】:

  • 这根本不是有效的 JSON,属性都应该有引号才有效。
  • 您是否要解析整个内容?能说清楚一点吗?
  • 我感觉您从 API 获得了有效的 JSON,但它已经被解析了。例如,如果您使用 jQuery.ajax 并指定了 json 数据类型来将请求发送到服务器。在这种情况下,您可能已将解析对象的日志输出粘贴到您的问题中。如果发生这种情况,那么您根本不需要JSON.parse()。如果不是这种情况,我建议您粘贴代码示例,以便更容易看到您在做什么。
  • @Marconius 我很确定它是以字符串形式出现的,而不是解析的 JSON。当 webhook 进入时,初始负载被 bodyparser 解析为 JSON,我得到这个负载:{ event_key: 'contact.edit', object_type: 'contact', object_key: '[{id:1057781, api_url:\'\', timestamp: 2017-07-11T19:24:41.000Z},{id:1035169, api_url:\'\', timestamp: 2017-07-11T19:23:56.000Z}]', api_url: '' } 如您所见,object_key 表示为字符串。我试过用 JSON.parse 解析那部分,但它会返回一个错误。

标签: javascript json node.js infusionsoft


【解决方案1】:

日期采用 ISO 格式,因此您可以使用几个正则表达式将字符串预处理为 JSON

string = "[...]"; 
string.replace(/(\d{4}-\d_2+-\d{2} ... /g, '"$1"'); // enclose dates in quotes
string.replace(/'/g, '"'); // replace single quotes with double quotes
string.replace(/id/g, '"id"'); // enclose id in double quotes
// repeat for api_url and timestamp

data = JSON.parse(string);

【讨论】:

    【解决方案2】:

    通过一些字符串操作和对字符串部分的迭代,我们可以将此响应解析为一个有效 JS 对象的数组。

    我已经运行了下面的代码,我得到了一个 JS 对象数组,它们映射到数组字符串中的每个“对象”。它还将无效的时间戳值转换为 JS 日期对象。

    let args = "[{id:1049105, api_url:'', timestamp: 2017-07-12T00:34:36.000Z},{id:993221, api_url:'', timestamp: 2017-07-12T00:34:18.000Z}]"
    
    let splitArgs = args.split('},')
    // Create an Array of parsed Objects
    let objs = splitArgs.map(arg => {
        // remove whitespace
        let cleanArg = arg.trim()
    
        // Remove enclosing [ { } ] characters
        if (arg.startsWith('[')) {
            cleanArg = cleanArg.substr(1, arg.length)
        }
        if (cleanArg.startsWith('{')) {
            cleanArg = cleanArg.substr(1, arg.length)
        }
        if (cleanArg.endsWith(']')) {
            cleanArg = cleanArg.substr(0, arg.length - 1)
        }
        if (cleanArg.endsWith('}')) {
            cleanArg = cleanArg.substr(0, arg.length - 1)
        }
    
        // Remove any quotations and then split each of the properties out  
        let props = cleanArg.replace(/[\']+/, '').split(',')
    
        // For each prop, get the value and assign it to the new object
        // that will be returned by reduce()
        return props.reduce((obj, prop) => {
            let splitIndex = prop.indexOf(':')
            let key = prop.substr(0, splitIndex)
            let val = prop.substr(splitIndex + 1, prop.length)
    
            if (key.toLowerCase() === 'timestamp') {
                obj[key] = (new Date(val))
            } else {
                obj[key] = val
            }
            return obj
        }, {})
    })
    
    console.log(objs.map(obj => { return obj.id })) // [1049105, 993221]
    

    【讨论】:

    • @BritGwaltney 你查看我更新的答案了吗?
    【解决方案3】:

    我是scanf的作者,你想试试这个吗:

    const {sscanf} = require('scanf');
    
    let str = `[{id:1049105, api_url:'', timestamp: 2017-07-12T00:34:36.000Z},{id:993221, api_url:'', timestamp: 2017-07-12T00:34:18.000Z}]`;
    let chunks = str.split('},{');
    
    for (let chunk of chunks) {
      let obj = sscanf(chunk, "id:%d, api_url:%s, timestamp: %s}", 'id', 'api_url', 'timestamp')
      console.log(obj);
    }
    
    /*
    { id: 1049105,
      api_url: '\'\'',
      timestamp: '2017-07-12T00:34:36.000Z' }
    { id: 993221,
      api_url: '\'\'',
      timestamp: '2017-07-12T00:34:18.000Z' }
    */
    

    可能存在使用问题或BUG,您可以提交issue获取更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 2018-06-11
      相关资源
      最近更新 更多