Python yaml.load 中遇到“不可接受的字符 #x0095:“<unicode string>”中不允许特殊字符,位置 268”错误

Rob*_*Wei 2 python yaml

将 YAML 格式传输到 Python 字典对象时,我遇到“不可接受的字符 #x0095:“”,位置 25 中不允许特殊字符”错误消息。
可能的解决方案是什么?

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

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

Ant*_*hon 5

YAML规范明确规定 YAML 流仅使用 Unicode 字符集的可打印子集。除 NEL ( \x85) 外,C1 控制块中不允许使用字符(即字符\x80- \x9F)。

这几乎是有效的 YAML:

d = 'tended (Journaled)"\n - " Support plug and play"\n'
Run Code Online (Sandbox Code Playgroud)

你只需要"在它前面和:键后面加上一个:

d = '"tended (Journaled)":\n - " Support plug and play"\n'
Run Code Online (Sandbox Code Playgroud)

(虽然我不确定Journaled是否是正确的英文)

以下不是 YAML:

d = '"tended (Journaled)":\n  - "\x95 Support plug and play"\n'
Run Code Online (Sandbox Code Playgroud)

因为\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)))
Run Code Online (Sandbox Code Playgroud)

这使:

{'tended (Journaled)': [' Support plug and play']}
Run Code Online (Sandbox Code Playgroud)

无需任何进一步的手动干预。

如果您取消注释该行

        # res += '\\x{:x}'.format(ord(x))
Run Code Online (Sandbox Code Playgroud)

你得到的输出:

{'tended (Journaled)': ['\x95 Support plug and play']}
Run Code Online (Sandbox Code Playgroud)