简略粗犷,间接上代码,
会把{"a":1,"a":2}解析成{"a":[1,2]}
附上npm链接:clarinet

var clarinet = require("clarinet");class InvalidJSON {    result = {}    /**     * @description 进入的括号层数     */    bracketCount = 0    /**     * @type { Array<{ type: 'array'; value: any[] } | { type: 'object'; arrayKeys: string[]; arrayKeysMap: { [key: string]: boolean; }; keys: string[]; value: { [key: string]: any } }> }     */    queue = []        get lastQueue() {        const queue = this.queue        return queue[queue.length - 1]    }        queuePop() {        this.queue.pop()        this.bracketCount--    }        queuePush(item) {        this.queue.push(item)        this.bracketCount++    }        onopenobject(key) {        // console.log('onopenobject', key)        const value = {}        this.bracketCount === 0 && (this.result = value)        this.lastQueue && this.onvalue(value)        this.queuePush({ keys: [key], arrayKeys: [], arrayKeysMap: {}, type: 'object', value })    }        onkey(key) {        // console.log('onkey', key)        const { keys, type, arrayKeys } = this.lastQueue        if (type !== 'object') { return }        keys.includes(key) && arrayKeys.push(key)        keys.push(key)    }        onvalue(v) {        // console.log('onvalue', v)        const { type, value, keys, arrayKeysMap, arrayKeys } = this.lastQueue        if (type === 'array') {            value.push(v)        } else if (type === 'object') {            const lastKeys = keys[keys.length - 1]            if (arrayKeys.includes(lastKeys)) {                if (!arrayKeysMap[lastKeys]) {                    arrayKeysMap[lastKeys] = true                    value[lastKeys] = [value[lastKeys]]                }                value[lastKeys].push(v)            } else {                value[lastKeys] = v            }        }    }        oncloseobject() {        // console.log('onclosearray')        this.queuePop()    }        onopenarray() {        // console.log('onopenarray')        const value = []        this.bracketCount === 0 && (result = value)        this.lastQueue && this.onvalue(value)        this.queuePush({ type: 'array', value })    }        onclosearray() {        // console.log('onclosearray')        this.queuePop()    }    /**     * @param { string } json 不非法的json     */    parse(json) {        this.bracketCount = 0        this.result = {}        this.queue = []        this.parser.write(json).close()        return this.result    }        parser    constructor() {        const parser = clarinet.parser()        const parserEvents = ['value', 'openobject', 'key', 'closeobject', 'openarray', 'closearray']        parserEvents.forEach(event => {            const eventName = `on${event}`            parser[eventName] = (...args) => this[eventName](...args)        })        this.parser = parser    }}const invalidJSON = new InvalidJSON()console.log(JSON.stringify(invalidJSON.parse('{"p":7,"p": 9,"w":3,"q":[0,8],"g":77,"g":{"a":100,"d":{"z":2},"d":{"z":3}}}')))

原理:clarinet会解析json字符串,在每个json字符串关键点触发回调,
如开始一个object,进入一个key,进入一个value,开始一个array,
利用这些回调,拼装出冀望的格局