Как разбить строку на несколько строк и сохранить пробелы в YAML?

Обратите внимание, что вопрос аналогичен, например этот, но по-прежнему отличается тем, что эти ответы не решают мою проблему:

  • Для ввода управляющих символов, например, \x08, мне кажется, что мне нужно использовать двойные кавычки ".
  • Все пробелы должны быть сохранены точно так, как указано. Для разрывов строк я использую явно \n.

У меня есть некоторые строковые данные, которые мне нужно сохранить в YAML, например:

  • " This is my quite long string data "
  • "This is my quite long string data"
  • "This_is_my_quite_long_string_data"
  • "Sting data\nwhich\x08contains control characters"

и нужно в YAML как-то вроде этого:

Key: "  This  is  my" +
     "  quite  long " +
     " string  data  "

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

Скалярные стили блоков блока YAML (>, |) здесь не помогут, поскольку они не позволяют экранировать, и даже выполняют некоторую пробельную дескрипцию, замену новой строки/пространства, которая бесполезна для моего случая.

Похоже, что единственный способ - использовать двойное цитирование " и обратную косую черту \, например:

Key: "\
  This is \
  my quite \
  long string data\
  "

Попытка сделать это в онлайн-парсер YAML приводит к "This is my quite long string data", как ожидалось.

Но он, к сожалению, терпит неудачу, если одна из "подстрок" ​​имеет ведущее пространство, например:

Key: "\
  This is \
  my quite\
   long st\
  ring data\
  "

Это приводит к "This is my quitelong string data", удаляет пробел между словами quite и long этого примера. Единственное, что приходит мне на ум, чтобы решить это, - заменить первое ведущее пространство каждой подстроки на \x20 следующим образом:

Key: "\
  This is \
  my quite\
  \x20long st\
  ring data\
  "

Как я выбрал YAML для получения максимально удобного для человека формата, я считаю, что \x20 немного уродливое решение. Может быть, кто-то знает лучший подход?

Для сохранения читаемости человеком я также не хочу использовать !!binary для этого.

Ответ 1

Вместо \x20 вы можете просто избежать первого пространства без отступа в строке:

Key: "\
  This is \
  my quite\
  \ long st\
  ring data\
  "

Это работает с несколькими пробелами, вам нужно только избежать первого.

Ответ 2

Вы правы в своем наблюдении, что управляющие символы могут быть представлены только в двойных кавычках.

Однако анализатор не выполняет fail, если подстроки (в YAML говорят: строки продолжения) имеют ведущее пространство. Это неверно ваша интерпретация стандарта YAML. В стандарте явно указано, что для многострочных двойных кавычек:

Все символы верхнего и нижнего пробелов исключаются из содержимого.

Таким образом, вы можете поместить столько пробелов, сколько хотите, до long, как вы хотите, это не изменит ситуацию.

Репрезентатор для двойных кавычек для Python (как в ruamel.yaml, так и в PyYAML) всегда представляет новые строки как \n. Я не знаю представителей YAML на других языках, где у вас есть больше контроля над этим (и, например, получите двойные символы новой строки для представления \n в ваших двойных кавычках). Поэтому вам, вероятно, придется написать своего представителя.

При написании репрезентатора вы можете попытаться сделать разрыв строки умным, поскольку он минимизирует количество экранированных пробелов (путем помещения их между словами в одной строке). Но особенно в строках с высоким соотношением "двойное пространство и слово", в сочетании с небольшой шириной для работы, будет трудно (если не невозможно) обойтись без экранированных пробелов.

Такой представитель должен ИМО сначала проверить, требуется ли двойное цитирование (т.е. есть контрольные символы, кроме строк новой строки). Если нет, и есть новые строки, вы, вероятно, лучше представляете строку в виде словарного массива в стиле блока (для которого не исключаются пробелы в начале или конце строки).