简单粗暴,直接上传代码,它会将{"a":1,"a":2}解析成{"a":[1,2]}附上npm链接:clarinet原链接segmentfaultvarclarinet=require("clarinet");classInvalidJSON{result={}/***@description输入的括号数量*/bracketCount=0/***@type{Array<{type:'array';值:任何[]}|{类型:“对象”;数组键:字符串[];arrayKeysMap:{[key:string]:boolean;};键:字符串[];value:{[key:string]:any}}>}*/queue=[]getlastQueue(){constqueue=this.queuereturnqueue[queue.length-1]}queuePop(){this.queue.pop()this.bracketCount--}queuePush(item){this.queue.push(item)this.bracketCount++}onopenobject(key){//console.log('onopenobject',key)constvalue={}this.bracketCount===0&&(this.result=value)this.lastQueue&&this.onvalue(value)这个。queuePush({keys:[key],arrayKeys:[],arrayKeysMap:{},type:'object',value})}onkey(key){//console.log('onkey',key)const{keys,type,arrayKeys复制代码}=this.lastQueueif(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.lastQueueif(type==='array'){value.push(v)}elseif(type==='对象'){constlastKeys=keys[keys.length-1]if(arrayKeys.includes(lastKeys)){if(!arrayKeysMap[lastKeys]){arrayKeysMap[lastKeys]=truevalue[lastKeys]=[value[lastKeys]]}值[lastKeys].push(v)}else{value[lastKeys]=v}}}oncloseobject(){//console.log('onclosearray')this.queuePop()}onopenarray(){//console.log('onopenarray')constvalue=[]this.bracketCount===0&&(this.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=0this.result={}this.queue=[]this.parser.write(json).close()returnthis.result}parserconstructor(){constparser=clarinet.parser()constparserEvents=['value','openobject','key','closeobject','openarray','closearray']parserEvents.forEach(event=>{consteventName=`on${event}`解析器[eventName]=(...args)=>this[eventName](...args)})this.parser=parser}}constinvalidJSON=newInvalidJSON()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串的每个关键点触发回调,比如开始一个对象,输入一个键,输入一个值,开始一个数组,利用这些回调组装出想要的格式
