如何在python中存储或读取yaml中的文字回车符和换行符

Rud*_*ker 8 python yaml

我一整天都在努力解决这个问题.我似乎无法在网上找到答案.我有一个yaml文档,为我的消息/响应服务器存储一些服务器配置,其中一个参数是"message_terminator".正如您所猜测的那样,这是我的服务器知道要查找的客户端发送的消息的消息终止符.

\r\n 
Run Code Online (Sandbox Code Playgroud)

是telnet发送的默认值,所以我已经设置了它.

Yaml文件:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: \r\n
Run Code Online (Sandbox Code Playgroud)

我想要做的是读取message_terminator值作为实际的回车和换行或将其从其字符串表示转换为其二进制转义码:return和换行,而不是字符串表示"\ r \n"

例如,如果我在python中:

print('\r\n')
Run Code Online (Sandbox Code Playgroud)

它打印回车和换行符,而不是字符.但是,如果我从python中读取yaml配置中的值:

print(config['global']['message_terminator'])
Run Code Online (Sandbox Code Playgroud)

它打印出来的字符:

\r\n
Run Code Online (Sandbox Code Playgroud)

更改Yaml文档并添加如下引号:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: '\r\n'
Run Code Online (Sandbox Code Playgroud)

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: b'\r\n'
Run Code Online (Sandbox Code Playgroud)

甚至

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: !!str \r\n
Run Code Online (Sandbox Code Playgroud)

要么

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: !!python/bytes b'\r\n'
Run Code Online (Sandbox Code Playgroud)

没有效果.打印出消息终止符时,它会打印字符.当它通过网络发送给客户端时,它的字符.

我也尝试过这样的事情:

print(bytes(config['global']['message_terminator'], 'utf-8').encode('unicode_escape'))
Run Code Online (Sandbox Code Playgroud)

它仍然只打印出人物.

请原谅我,如果我完全错了或者遗漏了一些大事.我仍在研究字符串,字节,原始字符串等之间的所有区别.欢迎任何建议或指示.谢谢你的时间.

编辑@Jan:当它在解释器中执行时,它可以工作.我打印了一个马车和换行符.不是人物.

>>> text = """
... val: "hello\\n\\rnew line"
... """
>>> text
'\nval: "hello\\n\\rnew line"\n'
>>> print(text)

val: "hello\n\rnew line"

>>> import yaml
>>> data = yaml.load(text)
>>> data
{'val': 'hello\n\rnew line'}
>>> print(data['val'])
hello
new line
>>> 
Run Code Online (Sandbox Code Playgroud)

但是在我的主代码中,当我从yaml文件加载时,它会打印\ r \n而不是实际的回车符和换行符.这个python代码:

TERM = config['global']['message_terminator']
print(TERM)
print(config['global']['message_terminator'])
print("netcmd server started on port", PORT)
Run Code Online (Sandbox Code Playgroud)

在终端打印:

$ python3 netcmd.py
\r\n
\r\n
netcmd server started on port 7040
Run Code Online (Sandbox Code Playgroud)

为了澄清,我想要回车和换行的动作,而不是字符表示.

编辑2: 问题解决了.我在Jan的Update之后更改了yaml文件:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: "\\r\\n"
Run Code Online (Sandbox Code Playgroud)

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: "\r\n"
Run Code Online (Sandbox Code Playgroud)

现在一切正常,python代码打印出一个实际的回车符和从yaml文件读取的换行符.

Jan*_*sky 8

YAML允许使用\字符转义,但您必须将值放入引号:

>>> text = """
... val: "hello\\n\\rnew line"
... """
...
>>> text
'\nval: "hello\\n\\rnew line"\n'
>>> data = yaml.load(text)
>>> data
{'val': 'hello\n\rnew line'}
Run Code Online (Sandbox Code Playgroud)

因此,您的文件global将按如下方式工作:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: "\r\n"
Run Code Online (Sandbox Code Playgroud)

YAML规范1.2的第5.7节:

5.7.逃脱的角色

必须转义所有不可打印的字符.YAML转义序列使用大多数现代计算机语言常用的"\"符号.必须将每个转义序列解析为适当的Unicode字符.原始转义序列是演示细节,不得用于传达内容信息.

请注意,转义序列仅在双引号标量中进行解释.在所有其他标量样式中,"\"字符没有特殊含义,并且不可打印的字符不可用.

  • 更具体地说,**仅当您使用双引号**时才有效.单引号不起作用 (4认同)