如何将Minecraft NBT数据转为JS对象/JSON?Chrome为何可解析?
Minecraft NBT转JSON/JS对象的解析问题
我正在开发一款在线工具,需要将Minecraft通过/data get命令导出的NBT数据字符串转换为原生JavaScript对象或JSON格式。
待转换的NBT数据示例
const NbtString = "{ForgeCaps:{},Items:[{Count:1b,Slot:0b,id:\"the_vault:card\",tag:{data:{entries:[{colors:[\"RED\"],groups:[\"Utility\",\"Stat\",\"Essence\"],model:\"the_vault:card/icon/mana_regeneration#inventory\",modifier:{config:{attribute:\"the_vault:mana_regen\",maxTier:5b,pool:[{config:'{\"min\":0.01,\"max\":0.01,\"step\":0.01}',tier:1b},{config:'{\"min\":0.02,\"max\":0.02,\"step\":0.01}',tier:2b},{config:'{\"min\":0.03,\"max\":0.03,\"step\":0.01}',tier:3b},{config:'{\"min\":0.04,\"max\":0.04,\"step\":0.01}',tier:4b},{config:'{\"min\":0.05,\"max\":0.05,\"step\":0.01}',tier:5b}]},type:\"gear\",values:[{tier:1b,value:0.01f},{tier:2b,value:0.02f},{tier:3b,value:0.03f},{tier:4b,value:0.04f},{tier:5b,value:0.05f}]},name:'{\"text\":\"Mana Regeneration Card\"}'}],tier:1b}}},{Count:1b,Slot:1b,id:\"the_vault:card\",tag:{data:{entries:[{colors:[\"RED\",\"GREEN\",\"BLUE\"],groups:[\"Wild\",\"Stat\",\"Temporal\",\"Resource\",\"Arcane\",\"Evolution\"],modifier:{config:{maxTier:1b},type:\"dummy\"},name:'{\"text\":\"Blue Wild Card\"}'}],tier:1b}}},{Count:1b,Slot:2b,id:\"the_vault:card\",tag:{data:{entries:[{colors:[\"BLUE\"],condition:{config:{tiers:[{pool:[{filters:[{colorFilter:[{value:[\"GREEN\"],weight:1b},{value:[\"BLUE\"],weight:1b},{value:[\"YELLOW\"],weight:1b},{value:[\"RED\"],weight:1b}],groupFilter:[{value:[\"Stat\"],weight:1b},{value:[\"Resource\"],weight:1b},{value:[\"Evolution\"],weight:1b}],minCount:{max:10b,min:7b,type:\"uniform\"},neighborFilter:[{weight:100b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{value:[\"GREEN\"],weight:1b},{value:[\"BLUE\"],weight:1b},{value:[\"YELLOW\"],weight:1b},{value:[\"RED\"],weight:1b}],groupFilter:[{value:[\"Stat\"],weight:1b},{value:[\"Resource\"],weight:1b},{value:[\"Evolution\"],weight:1b}],minCount:{max:4b,min:3b,type:\"uniform\"},neighborFilter:[{value:[\"ROW\"],weight:1b},{value:[\"COLUMN\"],weight:1b},{value:[\"DIAGONAL\"],weight:1b},{value:[\"ADJACENT\"],weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{weight:1b}],groupFilter:[{value:[\"Arcane\"],weight:1b}],maxCount:{max:3b,min:1b,type:\"uniform\"},neighborFilter:[{weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{weight:1b}],groupFilter:[{value:[\"Stat\"],weight:1b},{value:[\"Resource\"],weight:1b},{value:[\"Evolution\"],weight:1b}],maxCount:{max:6b,min:4b,type:\"uniform\"},minCount:{max:2b,min:1b,type:\"uniform\"},neighborFilter:[{weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{value:[\"GREEN\"],weight:1b},{value:[\"BLUE\"],weight:1b},{value:[\"YELLOW\"],weight:1b},{value:[\"RED\"],weight:1b}],groupFilter:[{weight:1b}],maxCount:{max:6b,min:4b,type:\"uniform\"},minCount:{max:2b,min:1b,type:\"uniform\"},neighborFilter:[{weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{weight:1b}],groupFilter:[{weight:1b}],maxCount:{max:2b,min:1b,type:\"uniform\"},neighborFilter:[{value:[\"ROW\"],weight:1b},{value:[\"COLUMN\"],weight:1b},{value:[\"DIAGONAL\"],weight:1b},{value:[\"ADJACENT\"],weight:1b}],tierFilter:[]}],weight:1b}],tier:1b}]},filters:[{tier:1b,value:[{maxCount:1b,neighborFilter:[\"COLUMN\"]]}]}],groups:[\"Offensive\",\"Arcane\"],model:\"the_vault:card/icon/ice_blast#inventory\",modifier:{config:{attribute:\"the_vault:added_ability_level\",maxTier:1b,pool:[{config:'{\"abilityKey\":\"Ice_Bolt_Blast\",\"levelChange\":1}',tier:1b}]},type:\"gear\",values:[{tier:1b,value:{ability:\"Ice_Bolt_Blast\",levelChange:1}}]},name:'{\"text\":\"Glacial Blast Card\"}'}],tier:1b}}},{Count:1b,Slot:3b,id:\"the_vault:card\",tag:{data:{entries:[{colors:[\"GREEN\"],groups:[\"Utility\",\"Scaling\"],model:\"the_vault:card/icon/healing_efficiency#inventory\",modifier:{config:{attribute:\"the_vault:healing_effectiveness\",maxTier:5b,pool:[{config:'{\"min\":0.002,\"max\":0.002,\"step\":1.0}',tier:1b},{config:'{\"min\":0.004,\"max\":0.004,\"step\":1.0}',tier:2b},{config:'{\"min\":0.006,\"max\":0.006,\"step\":1.0}',tier:3b},{config:'{\"min\":0.008,\"max\":0.008,\"step\":1.0}',tier:4b},{config:'{\"min\":0.01,\"max\":0.01,\"step\":1.0}',tier:5b}]},type:\"gear\",values:[{tier:1b,value:0.002f},{tier:2b,value:0.004f},{tier:3b,value:0.006f},{tier:4b,value:0.008f},{tier:5b,value:0.01f}]},name:'{\"text\":\"Scaling Healing Efficiency Card\"}',scaler:{config:{tiers:[{pool:[{filters:[{colorFilter:[{value:[\"GREEN\"],weight:1b},{value:[\"BLUE\"],weight:1b},{value:[\"YELLOW\"],weight:1b},{value:[\"RED\"],weight:1b}],groupFilter:[],neighborFilter:[{value:[\"ROW\"],weight:5b},{value:[\"COLUMN\"],weight:5b},{value:[\"DIAGONAL\"],weight:3b},{value:[\"ADJACENT\"],weight:5b},{value:[\"SURROUNDING\"],weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{value:[\"GREEN\"],weight:1b},{value:[\"BLUE\"],weight:1b},{value:[\"YELLOW\"],weight:1b},{value:[\"RED\"],weight:1b}],groupFilter:[{value:[\"Stat\"],weight:1b},{value:[\"Evolution\"],weight:1b},{value:[\"Resource\"],weight:1b}],neighborFilter:[{value:[\"ROW\"],weight:5b},{value:[\"COLUMN\"],weight:5b},{value:[\"DIAGONAL\"],weight:3b},{value:[\"ADJACENT\"],weight:5b},{value:[\"SURROUNDING\"],weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[],groupFilter:[{value:[\"Stat\"],weight:1b},{value:[\"Evolution\"],weight:1b},{value:[\"Resource\"],weight:1b}],neighborFilter:[{value:[\"ROW\"],weight:5b},{value:[\"COLUMN\"],weight:5b},{value:[\"DIAGONAL\"],weight:3b},{value:[\"ADJACENT\"],weight:5b},{value:[\"SURROUNDING\"],weight:1b}],tierFilter:[]}],weight:1b}],tier:1b}]},filters:[{tier:1b,value:[{colorFilter:[\"GREEN\"],groupFilter:[\"Evolution\"],neighborFilter:[\"SURROUNDING\"]]}]}]},tier:1b}}},{Count:1b,Slot:4b,id:\"the_vault:card\",tag:{data:{entries:[{colors:[\"GREEN\"],groups:[\"Resource\"],model:\"the_vault:vault_plating#inventory\",modifier:{config:{count:[{roll:{max:8b,min:3b,type:\"uniform\"},tier:1b}],highlightColor:65280,loot:[{item:\"the_vault:vault_plating\",weight:1.0d}],maxTier:1b,task:\"@easy\",tooltip:'{\"color\":\"gold\",\"extra\":[{\"color\":\"#FFFFFF\",\"text\":\"${count}\"},{\"color\":\"yellow\",\"text\":\" Vault Plating \"},{\"text\":\"${task}\"}],\"text\":\"+\"}'},counts:[{count:7b,tier:1b}],task:{children:[],config:{filter:\"@the_vault:living\"},counter:{baseTarget:7b,config:{target:{max:7b,min:6b,type:\"uniform\"},variables:{targetTierContribution:1b}},current:0b,target:7b,type:\"target\"},operating:0b,renderer:{tooltip:'{\"text\":\"per ${target} Living Chests looted\"}',type:\"card\"},type:\"loot_chest\"},type:\"task_loot\",uuid:[I;-1335797438,959268282,-1831723904,956595013]},name:'{\"text\":\"Vault Plating Card\"}'}],tier:1b}}}],id:\"quark:variant_chest\",x:-317,y:112,z:473}"
已实现的解析函数
我写了一个parseNBT函数做基础格式修正:
function parseNBT(data) { return data // Convert "1b", "2b", etc., to plain integers (byte to int) .replace(/(\d+)b/g, '$1') // Convert "1.0f", "0.2f", etc., to plain numbers (float to number) .replace(/(\d*\.?\d+)f/g, '$1') // Convert "1.0d", "0.5d" (double) to plain numbers .replace(/(\d*\.?\d+)d/g, '$1') // Handle "uuid:[I;...]" - Convert to valid JSON array .replace(/uuid:\[I;([\d,-]+)\]/g, function (match, p1) { return `"uuid": [${p1}]`; }) }
遇到的问题
处理后的字符串能在Chrome控制台直接解析为对象,但用JSON.parse时会报错,主要问题:
- 未加引号的键(比如
Count、Slot)不符合JSON规范,尤其是值包含冒号的情况(如"the_vault:card"); - 嵌套的JSON字符串(比如
config字段的值是转义后的JSON)处理复杂,容易破坏结构。
两个问题请教
- Chrome控制台是怎么实现这种非标准字符串解析的?能不能在代码里复用这个逻辑?
- 如果不能复用,该怎么修正格式让字符串符合JSON规范,能被
JSON.parse正确解析?
内容的提问来源于stack exchange,提问作者ThomasNL
相关产品推荐
相关产品推荐

