【问题标题】:Python - Reading YAML file with escape characters and escape themPython - 使用转义字符读取 YAML 文件并将其转义
【发布时间】:2022-10-05 09:15:03
【问题描述】:

我有一个 yaml 文件,其条目中包含 Latex-strings,特别是带有许多未转义的转义符号 \\。该文件可能看起来像这样

content: 
    - \"explanation\"   : \"\\text{Explanation 1} \"
      \"formula\"       : \"\\exp({{a}}^2)  =  {{d}}^2  -  {{b}}^2\"
    - \"explanation\"   : \"\\text{Explanation 2}\"
      \"formula\"       : \"{{b}}^2         = {{d}}^2      -  \\exp({{a}}^2) \"

所需的输出形式(在 python 中)如下所示:

config = {
            \"content\" : [
            {\"explanation\" : \"\\\\text{Now} \",
              \"formula\"    : \"\\\\exp({{a}}^2)  =  {{d}}^2  -  {{b}}^2\"},
            {\"explanation\" : \"\\\\text{With}\",
              \"formula\"    : \"{{a}}^2        = {{d}}^2 + 3     ++  {{b}}^2\"}
                    ]
         }

\\ 被转义的地方,而不是使用 re.escape(string) 时的 \"{\" 和 \"}\"。

path = \"config.yml\"
with open(path, \"r\",encoding = \'latin1\') as stream: 
    config1 = yaml.safe_load(stream)

with open(path, \"r\",encoding = \'utf-8\') as stream: 
    config2 = yaml.safe_load(stream)

# Codecs
import codecs
with codecs.open(path, \"r\",encoding=\'unicode_escape\') as stream:
    config3 = yaml.safe_load(stream)
    
with codecs.open(path, \"r\",encoding=\'latin1\') as stream:
    config4 = yaml.safe_load(stream)

with codecs.open(path, \'r\', encoding=\'utf-8\') as stream:
    config5 = yaml.safe_load(stream)

# 
with open(path, \"r\", encoding = \'utf-8\') as stream:
    stream = stream.read() 
    config6 = yaml.safe_load(stream)

with open(path, \"r\", encoding = \'utf-8\') as stream:
    config7 = yaml.load(stream,Loader = Loader)

这些解决方案似乎都不起作用,例如\"unicode-escape\" 选项仍然读入 \\x1bxp({{a}}^2) 而不是 \\exp({{a}}^2)

我能做些什么? (字典条目稍后被提供给 Latex-Parser,但我无法手动逃脱所有 \\ 标志。)。

  • 是什么生成了 YAML 文件? \\n\\e\\t 在 YAML 中用双引号括起来时都是特殊字符。您需要重写生成 YAML 文件的任何内容,并使其不将这些值括在双引号中。除非您编写自己的非 YAML 解析器,否则这些字符将被解释为特殊字符。
  • 有没有办法解决这个问题?是不是没有函数从文件中读取 yaml 字符串并在 yaml 解析器读取它之前转义 \\ ?
  • 是否有任何文件格式可以读取乳胶字符串并转义它们的 \\ 符号?
  • edit您的问题提供minimal reproducible example。反而\"文件可能看起来像这样\"显示来自cat config.yml(或type config.yml)的输出。

标签: python-3.x character-encoding yaml


【解决方案1】:

\n\e\t 在 YAML 中双引号时都是特殊字符。由于您基本上是在要求 YAML 解析器盲目地将双引号文本视为纯文本,以便可以按字面意思解释这些序列,因此一种解决方法是使用纯文本的扫描仪方法对双引号文本的扫描仪方法进行猴子修补:

import yaml
from unittest.mock import patch

with patch('yaml.scanner.Scanner.fetch_double', yaml.scanner.Scanner.fetch_plain):
    with open('config.yml') as stream:
        config = yaml.safe_load(stream)

使用您的示例输入,config 将变为:

{
    'content': [
        {'"explanation"': '"\\text{Explanation 1} "',
         '"formula"': '"\\exp({{a}}^2)  =  {{d}}^2  -  {{b}}^2"'},
        {'"explanation"': '"\\text{Explanation 2}"',
         '"formula"': '"{{b}}^2         = {{d}}^2      -  \\exp({{a}}^2) "'}
    ]
}

演示:https://replit.com/@blhsing/WaryDirectWorkplaces

请注意,这种方法带来的明显后果是您失去了双引号的所有功能。如果配置文件有其他需要正确转义的双引号文本,这将无法正确解析它们。但是,如果配置文件只有您在问题中发布的那种输入,它将有助于以您喜欢的方式解析它,而无需修改生成此类(不正确的)YAML 文件的代码(因为大概您在问这个问题,因为您无权修改生成 YAML 文件的代码)。

【讨论】:

    猜你喜欢
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    相关资源
    最近更新 更多