面对&#34;不可接受的字符#x0095:&#34; <unicode string =“”>&#34;,位置268&#34;中不允许使用特殊字符。 Python yaml.load中的错误

时间:2017-08-24 21:19:40

标签: python yaml

我正面对不可接受的角色#x0095:&#34;&#34;,位置25&#34;中不允许使用特殊字符。将YAML格式传输到Python字典对象时出现错误消息 什么是可能的解决方案?

d = 'tended (Journaled)"\n  - "\x95 Support plug and play"\n'
a = yaml.load(d)

要传输的字符串被删节,而不是正确的YAML格式,但我认为在这种情况下它是无关紧要的。 我使用的是Python3

2 个答案:

答案 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']}