Как разобрать строковый массив как 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);