我正面对不可接受的角色#x0095:"",位置25"中不允许使用特殊字符。将YAML格式传输到Python字典对象时出现错误消息 什么是可能的解决方案?
d = 'tended (Journaled)"\n - "\x95 Support plug and play"\n'
a = yaml.load(d)
要传输的字符串被删节,而不是正确的YAML格式,但我认为在这种情况下它是无关紧要的。 我使用的是Python3
答案 0 :(得分:1)
您必须检查乱码数据是否包含无效字符。幸运的是,YAML阅读器有一个异常,可以产生必要的数据:
import yaml
try:
d = 'tended (Journaled)"\n - "\x95 Support plug and play"\n'
a = yaml.load(d)
except yaml.YAMLError as e:
print("Parsing YAML string failed")
print("Reason:", e.reason)
print("At position: {0} with encoding {1}".format(e.position, e.encoding))
print("Invalid char code:", e.character)
如果您运行此代码,则会准确显示您的角色\x95
是罪魁祸首。现在你必须更换/修复/询问用户,直到没有抛出异常。
答案 1 :(得分:0)
YAML specification明确指出YAML流仅使用Unicode字符集的可打印子集。除NEL(\x85
)外, C1控制块中的字符不允许(即字符\x80
- \x9F
)。
这几乎是有效的YAML:
d = 'tended (Journaled)"\n - " Support plug and play"\n'
您需要在其前面加"
并在密钥后面:
:
d = '"tended (Journaled)":\n - " Support plug and play"\n'
(虽然我不确定Journaled是否是正确的英语)
以下不是YAML:
d = '"tended (Journaled)":\n - "\x95 Support plug and play"\n'
因为\x95
位于C1控制块中。您必须手动替换这些字符,或将其删除。
ruamel.yaml
中没有多少可以帮助您转换此类非法字符,但您可以使用Reader
的非法字符正则表达式来扫描非法字符并删除它们:
from ruamel.yaml import YAML
from ruamel.yaml.reader import Reader
yaml = YAML(typ='safe')
def strip_invalid(s):
res = ''
for x in s:
if Reader.NON_PRINTABLE.match(x):
# res += '\\x{:x}'.format(ord(x))
continue
res += x
return res
d = '"tended (Journaled)":\n - "\x95 Support plug and play"\n'
print(yaml.load(strip_invalid(d)))
给出:
{'tended (Journaled)': [' Support plug and play']}
没有任何进一步的人工干预。
如果您取消注释该行
# res += '\\x{:x}'.format(ord(x))
你得到输出:
{'tended (Journaled)': ['\x95 Support plug and play']}