Текстовый формат данных, который поддерживает многострочные строки
Я ищу текстовый формат данных, который поддерживает многострочные строки.
JSON не разрешает многострочные строки:
>>> import json
>>> json.dumps(dict(text='first line\nsecond line'))
'{"text": "first line\\nsecond line"}'
Мой желаемый результат:
{"text": "first line
second line"}
Этот вопрос касается ввода и вывода. Формат данных должен быть доступен для редактирования с помощью редактора, такого как vi, emacs или блокнот.
Мне все равно, если будут использоваться простые кавычки "
или трипсовые кавычки (например, в Python) """
.
Существует ли удобный для людей понятный формат обмена текстовыми данными, который поддерживает это?
Использовать регистр
Я хочу редактировать данные с многострочными строками с помощью vi
. Это не забавно, если данные находятся в формате json.
Ответы
Ответ 1
Думаю, вы должны рассмотреть формат YAML
. Он поддерживает нотацию блока, которая может сохранять новые строки, как это показано
data: |
There once was a short man from Ealing
Who got on a bus to Darjeeling
It said on the door
"Please don't spit on the floor"
So he carefully spat on the ceiling
Также существует множество парсеров для любых языков программирования, включая python (i.e pyYaml).
Также существует огромное преимущество, что любой действительный JSON - YAML.
Ответ 2
По поводу вашего комментария:
Я хочу использовать его для настройки. Много приложений изобретают их собственный язык настройки. Я хочу избежать этого. Но json и ConfigParser меня не удовлетворяет. Json не разрешает строки с newlines (только\n), а ConfigParser не позволяет вложенные данные структур. Следующее, что мне не хватает: валидация (но это другая тема).
Есть 3 основных варианта: ConfigParser, ConfigObj или YAML ( PyYAML) - каждый из них имеет свои плюсы и минусы. Все 3 лучше, чем JSON для вашего конфигурационного файла, используемого для использования.
Теперь, что лучше, зависит от того, что именно вы хотите сохранить в своем файле conf.
ConfigObj. Для настройки и проверки (ваш прецедент):
ConfigObj очень прост в использовании, тогда YAML (также ConfigParser). Поддерживает значения и типы по умолчанию, а также включает проверку (огромный плюс через ConfigParser).
Введение в ConfigObj
Когда вы выполняете проверку, каждый из членов вашей спецификации проверяются, и они подвергаются процессу, который преобразует значения в указанный тип. Отсутствуют значения, имеющие значения по умолчанию. in и validation возвращает либо True, чтобы указать успех, либо словарь с членами, которые не прошли проверку. Индивидуальные проверки и конверсии выполняются функциями, и добавление вашей собственной проверки функция очень проста.
P.S. Да, это позволяет многострочные значения.
Полезные ссылки:
Краткое руководство по ConfigObj
ConfigObj 5 Введение и ссылка
Есть солидные ответы SO, доступные при сравнении YAML vs ConfigParser vs ConfigObj:
Что лучше, ConfigObj или ConfigParser?
ConfigObj/ConfigParser против использования файла настроек YAML для Python
Ответ 3
Формат ini
также поддерживает многострочные строки; configparser из Python stdlib может справиться с этим. См. https://docs.python.org/3/library/configparser.html#supported-ini-file-structure.
Ответ 4
Если файлы используются только Python (без учета обмена), вы можете просто поместить свои данные в файл python script и импортировать это как модуль:
Данные
datum_1 = """ lorem
ipsum
dolor
"""
datum_list = [1, """two
liner"""]
datum_dict = {"key": None, "another": [None, 42.13]}
datum_tuple = ("anything", "goes")
Script
from data import *
d = [e for e in locals() if not e.startswith("__")]
print( d )
for k in d:
print( k, locals()[k] )
Выход
['datum_list', 'datum_1', 'datum_dict', 'datum_tuple']
datum_list [1, 'two\nliner']
datum_1 lorem
ipsum
dolor
datum_dict {'another': [None, 42.13], 'key': None}
datum_tuple ('anything', 'goes')
<ч/" > Обновление:
Код со словарным пониманием
from data import *
d = {e:globals()[e] for e in globals() if not e.startswith("__")}
for k in d:
print( k, d[k] )
Ответ 5
XML с ElementTree (стандартная библиотека) или lxml, если вы в порядке с накладными накладками:
Данные
<?xml version="1.0"?>
<data>
<string>Lorem
Ipsum
Dolor
</string>
</data>
Script
import xml.etree.ElementTree
root = xml.etree.ElementTree.parse('data.xml').getroot()
for child in root:
print(child.tag, child.attrib, child.text)
Выход
string {} Lorem
Ipsum
Dolor
Ответ 6
Если вы используете Python 2, я на самом деле думаю, что json может делать то, что вам нужно. Вы можете сбрасывать и загружать json во время декодирования и кодировать его с помощью string-escape
:
import json
config_dict = {
'text': 'first line\nsecond line',
}
config_str = json.dumps(config_dict).decode('string-escape')
print config_str
config_dict = json.loads(config_str.encode('string-escape'))
print config_dict
Выход
{"text": "first line
second line"}
{u'text': u'first line\nsecond line'}
Итак, вы можете использовать декодированную строку для редактирования JSON, включенных новых строк и при чтении, просто закодируйте с помощью escape-последовательности строк, чтобы вернуть словарь.
Ответ 7
Не уверен, правильно ли я понял ваш вопрос, но вы не просите что-то вроде этого?
my_config = {
"text": """first line
second line"""
}
print my_config