如何将nbtlib字符串转为NBT Compound对象并保留标签类型
保留类型将"Compound({'foo': Byte(1)})"格式字符串转为nbtlib Compound对象
需要把形如Compound({'foo': Byte(1)})的字符串转换成nbtlib的NBT Compound对象,但nbtlib.parse_nbt()仅支持解析{foo: 1}这种不带类型标注的格式。之前尝试用unpack()将Compound转为字符串再解析,会丢失标签类型信息——比如Byte、Long类型会被自动转为Int,无法保留原始类型。
问题复现代码
import nbtlib # 创建带Byte类型的Compound实例 compound = nbtlib.Compound() compound["foo"] = nbtlib.Byte(1) print(compound) >>> Compound({'foo': Byte(1)}) # unpack后丢失类型信息 string = str(compound.unpack()) print(string) >>> {'foo': 1} # 解析后类型被转为Int parsed = nbtlib.parse_nbt(string) print(parsed) >>> Compound({'foo': Int(1)})
解决方案:直接解析带类型标注的字符串
既然unpack()会丢失类型,我们可以直接解析原始的Compound(...)格式字符串,提取每个键值对的类型和值,手动构建Compound对象:
import nbtlib import re def parse_compound_string(compound_str): # 提取Compound括号内的字典内容 match = re.match(r'Compound\(({.*})\)', compound_str) if not match: raise ValueError("输入字符串不是有效的Compound格式") inner_content = match.group(1) # 匹配每个带类型的键值对,比如 'foo': Byte(1) kv_regex = re.compile(r"'(\w+)': (\w+)\((\d+)\)") new_compound = nbtlib.Compound() for kv_match in kv_regex.finditer(inner_content): key = kv_match.group(1) type_name = kv_match.group(2) value = int(kv_match.group(3)) # 获取对应的nbtlib类型并创建实例 nbt_type = getattr(nbtlib, type_name) new_compound[key] = nbt_type(value) return new_compound # 测试示例 test_str = "Compound({'foo': Byte(1), 'bar': Long(1234567890123), 'baz': Int(456)})" result = parse_compound_string(test_str) print(result) >>> Compound({'foo': Byte(1), 'bar': Long(1234567890123), 'baz': Int(456)})
方案说明
- 用正则表达式提取
Compound(...)内部的字典字符串,再逐个匹配每个键值对的类型(如Byte、Long)和对应数值 - 通过
getattr(nbtlib, type_name)动态获取对应的NBT类型类,创建类型实例后加入Compound - 完全保留原始标签类型,避免了
unpack()导致的类型丢失问题
内容的提问来源于stack exchange,提问作者Anthony C
相关产品推荐
相关产品推荐

