Как разобрать строковый массив как JSON?

Мне сложнее всего разобрать эту строку. Это может показаться простой задачей, но это сводит меня с ума. 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}]

Любая помощь будет принята с благодарностью.

3 ответа

С некоторыми манипуляциями со строками и итерацией по частям строки мы можем проанализировать этот ответ в массив допустимых объектов 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]

Я автор 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' }
*/

Там могут быть некоторые проблемы с использованием или ошибка, вы можете отправить вопрос для более.

Даты представлены в формате 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);
Другие вопросы по тегам