如何更改 pyyaml.ruamel.yaml 中字符串的默认引号

问题描述 投票:0回答:1

关于堆栈溢出有很多关于如何在 YAML 中保留引号的问题,但似乎没有问题询问如何在 pyyaml/ruamel.yaml 确定引号时仅更改默认值(从单引号到双引号)需要。

我知道大多数字符串不需要引用,我也不想引用它们。但是当需要的时候,如何更改默认引用呢?

我不想覆盖

style='"'
str
因为这会导致所有字符串被引用(包括 yaml 键,恶心),这不是我想要的。

我认为这可能就像添加一个 str 表示器并检查传入数据的类型一样简单,如果是 SingleQuotedScalarString,则转换为 DoubleQuotedScalarString 但我总是只收到

<class 'str'>
所以我想它并不那么简单。

pyyaml ruamel.yaml
1个回答
0
投票

ruamel.yaml
(因为我不记得在从 PyYAML 分叉之后更改过它,至少旧的 该包的版本),尝试转储不带引号的字符串。如果这不起作用,实际上 解析回字符串的渲染 YAML,以查看解析的 YAML 的类型是否会产生字符串 (而不是例如浮点数、布尔值、日期等),看看是否需要引用。

如果需要引用,则默认为双引号,除非可以使用单引号表示而不需要转义。

import sys
import ruamel.yaml


data = [
    "'single quoted string'",
    "quote that's not at the beginning",
    "'at the beginning only",
    "'at the beginning only and double quote (\") too ",
    "at the end only'",
    '"double quoted string"',
    'Germans write uberhaupt with " on the letter u',
    'special characters \x01',
    '"at the beginning only',
    '"at the beginning only and single quote (\') too ',
    'at the end only"',
    '3.14159',
    '2024-07-25',
    ruamel.yaml.scalarstring.SingleQuotedScalarString("'abc'"),  # this should NOT be affected
]

yaml = ruamel.yaml.YAML()
yaml.dump(data, sys.stdout)

给出:

- "'single quoted string'"
- quote that's not at the beginning
- "'at the beginning only"
- "'at the beginning only and double quote (\") too "
- at the end only'
- '"double quoted string"'
- Germans write uberhaupt with " on the letter u
- "special characters \x01"
- '"at the beginning only'
- "\"at the beginning only and single quote (') too "
- at the end only"
- '3.14159'
- '2024-07-25'
- '''abc'''

元素的样式(发射器收到事件时的事件) 由

choose_scalar_style()
ruamel.yaml.emitter.py
中的代码确定。

当您复制该方法的代码,将最后的

if
语句拆分为
or
并更改一行时,在需要时您总是会得到双引号:

yaml = ruamel.yaml.YAML()


def choose_scalar_style_as_long_as_it_is_double(self):
    if self.event.value == '' and self.event.ctag.handle == '!!':
        return None
    if self.analysis is None:
        self.analysis = self.analyze_scalar(self.event.value)
    if self.event.style == '"' or self.canonical:
        return '"'
    if (not self.event.style or self.event.style == '?' or self.event.style == '-') and (
        self.event.implicit[0] or not self.event.implicit[2]
    ):
        if not (
            self.simple_key_context and (self.analysis.empty or self.analysis.multiline)
        ) and (
            self.flow_level
            and self.analysis.allow_flow_plain
            or (not self.flow_level and self.analysis.allow_block_plain)
        ):
            return ""
        if self.event.style == '-':
            return ""
    self.analysis.allow_block = True
    if self.event.style and self.event.style in '|>':
        if (
            not self.flow_level
            and not self.simple_key_context
            and self.analysis.allow_block
        ):
            return self.event.style
    if not self.event.style and self.analysis.allow_double_quoted:
        if "'" in self.event.value or '\n' in self.event.value:
            return '"'
    # >>>>> split out what used to be:
    # if not self.event.style or self.event.style == "'":
    if not self.event.style:
        if self.analysis.allow_single_quoted and not (
            self.simple_key_context and self.analysis.multiline
        ):
            return '"'  # <<<<<<< this makes the difference
    elif self.event.style == "'":
        if self.analysis.allow_single_quoted and not (
            self.simple_key_context and self.analysis.multiline
        ):
            return "'"
    return '"'

yaml.Emitter.choose_scalar_style = choose_scalar_style_as_long_as_it_is_double

yaml.dump(data, sys.stdout)

给出:

- "'single quoted string'"
- quote that's not at the beginning
- "'at the beginning only"
- "'at the beginning only and double quote (\") too "
- at the end only'
- "\"double quoted string\""
- Germans write uberhaupt with " on the letter u
- "special characters \x01"
- "\"at the beginning only"
- "\"at the beginning only and single quote (') too "
- at the end only"
- "3.14159"
- "2024-07-25"
- '''abc'''

方法

choose_scalar_style
也会影响标签输出。如果这干扰了 您需要修改输出
process_scalar()
才能调用修改后的方法 (添加了不同的名称)。

© www.soinside.com 2019 - 2024. All rights reserved.