Остановить PyYaml от преобразования элемента yaml в список - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь загрузить следующий yaml:

yaml_string = """
key:
- [HELLO]
- another string
- another
"""
yaml.safe_load(yaml_string) # returns {"key": [["HELLLO"], "another_string", "another"}

, и в результате получается список, содержащий строку HELLO. Я хочу загрузить это строковое значение, равное

type(yaml.save_load(yaml_string).get("key")[0])
<class 'str'>

Поскольку yaml описывает какой-то вид комнад, отформатированных таким образом, его необходимо читать как строки, а не как последовательности. По сути, я хочу читать строки, начинающиеся и заканчивающиеся скобками. Как поясняется в комментарии ниже, к сожалению, невозможно добавить ", поскольку файлы yaml были созданы приложением Java с использованием Jackson, у которого не было проблем с превращением yaml в объект и обработкой записей, которые начинаются и заканчиваются со скобками в виде строк. Файлы для многих пользователей, чтобы начать добавлять кавычки.

Возможно ли это?

РЕДАКТИРОВАТЬ: Добавлен более полный пример

Ответы [ 3 ]

1 голос
/ 17 февраля 2020

объем [HELLO] с кавычками:

import yaml

yaml_string = """
key:
- "[HELLO]"
- another string
- another
"""

print(yaml.safe_load(yaml_string))

выходы

{'key': ['[HELLO]', 'another string', 'another']}
0 голосов
/ 18 февраля 2020

Синтаксис [] является частью синтаксиса YAML. Если вы создали это с помощью программы, и предполагается, что это строки, используемая вами программа неправильно реализовала YAML, поскольку строки должны быть заключены в кавычки.

Вы можете попробовать следующую экспериментальную perl скрипт для добавления кавычек вокруг [...]. Это основано на предположении, что ваши документы не используют последовательности стилей потока, которые должны быть реальными последовательностями. Также это может работать не во всех случаях.

Это определенно не будет работать, если строка имеет только открывающий [, но не закрывающий.

#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;

use YAML::LibYAML::API::XS;

my $yaml = <<'EOM';
key:
- [HELLO]
- another string
- another
- [HELLO2]
EOM

my @lines = split /(?<=\n)/, $yaml;

my @events;
YAML::LibYAML::API::XS::parse_string_events($yaml, \@events);
while (my $event = shift @events) {
    if ($event->{name} eq 'sequence_start_event' and $event->{style} == 2) {
        my $start = $event->{start};
        my $line = $start->{line};
        my $column = $start->{column};
        # Add single quote before [
        substr($lines[ $line ], $column, 0) = "'";
        # find the next matching `]`
        while (my $event = shift @events) {
            if ($event->{name} eq 'sequence_end_event') {
                my $end = $event->{end};
                my $line = $end->{line};
                # Add single quote after ]
                # add 1 because we modified the line already and added one char
                my $column = $end->{column} + 1;
                substr($lines[ $line ], $column, 0) = "'";
                last;
            }
        }
    }
}

$yaml = join '', @lines;
say $yaml;

Вы можете проделайте то же самое с Python, если у вас есть интерфейс к API libyaml.

Вывод:

key:
- '[HELLO]'
- another string
- another
- '[HELLO2]'
0 голосов
/ 17 февраля 2020

Если вы хотите получить в результате строку "HELLO", то удалите [...] вокруг нее в YAML:

yaml_string = """
key:
- HELLO
"""
print(yaml.safe_load(yaml_string))
# {'key': ['HELLO']}

Если вы хотите строку "[HELLO]" (вместо списка, содержащего строка "HELLO"), затем добавьте кавычки в YAML:

yaml_string = """
key:
- "[HELLO]"
"""
print(yaml.safe_load(yaml_string))
# {'key': ['[HELLO]']}
...