2016-08-17 28 views
15

Przeszukuję tekstowy format danych obsługujący ciągi wielowierszowe.Format danych tekstowych obsługujący ciągi wielowierszowe

JSON nie pozwala multilinii ciągi:

>>> import json 
>>> json.dumps(dict(text='first line\nsecond line')) 
'{"text": "first line\\nsecond line"}' 

My pożądane wyjście:

{"text": "first line 
second line"} 

To pytanie jest o wejściu i wyjściu. Format danych powinien być edytowalny za pomocą edytora takiego jak vi, emacs lub notepad.

Nie obchodzi mnie, czy proste cytaty " lub potrójne cytaty (jak w Pythonie) """ się przyzwyczają.

Czy istnieje łatwy do odczytania tekstowy format wymiany danych dla ludzi, który obsługuje to?

przypadków użycia

chcę edytować dane z multilinii strun z vi. To nie jest zabawne, jeśli dane są w formacie json.

+0

czy można opracować format/cel danych, np. Złożone struktury lub niektóre ustawienia/plik conf itp. –

+0

@NabeelAhmed Chcę go użyć do konfiguracji. Wiele aplikacji wymyśla własny język konfiguracji. Chcę tego uniknąć. Ale json i ConfigParser mnie nie satysfakcjonują. Json nie zezwala na ciągi znaków z znakami nowej linii (tylko \ n), a narzędzie ConfigParser nie zezwala na zagnieżdżanie struktur danych. Następna rzecz, której mi brakuje: Walidacja (ale jest to inny temat). Drogi Nabeelu, proszę zostawić nowy komentarz, jeśli czegoś brakuje. – guettli

+0

Myślę, że jeśli możesz zastąpić wynik zrzutu, to wynik powinien być prawidłowy. 'data = json.dumps (dict (text = 'first line \ nsecond line')) data = data.replace ('\\ n', '\ n') print (data)' –

Odpowiedz

21

Myślę, że powinieneś rozważyć format YAML. Obsługuje zapis bloku, który jest able to preserve newlines jak ten

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 

Ponadto istnieje wiele analizatorów dla wszelkiego rodzaju języków programowania, w tym python (tj pyYaml).

Istnieje również ogromna zaleta, którą można uznać za ważną: JSON is YAML. Format

+3

Wycofane dla limeryka. –

2

Jeśli pliki są używane tylko przez Python (z widokiem na wymianę), można po prostu umieścić swoje dane w pliku skryptowego Python i importować to jako moduł:

Danych

datum_1 = """ lorem 
ipsum 
dolor 
""" 
datum_list = [1, """two 
liner"""] 
datum_dict = {"key": None, "another": [None, 42.13]} 
datum_tuple = ("anything", "goes") 

skrypt

from data import * 
d = [e for e in locals() if not e.startswith("__")] 
print(d) 
for k in d: 
    print(k, locals()[k]) 

Wyjście

['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') 


Aktualizacja:

Kod z słowniku zrozumienia

from data import * 
d = {e:globals()[e] for e in globals() if not e.startswith("__")} 
for k in d: 
    print(k, d[k]) 
2

XML z ElementTree (biblioteki standardowej) lub lxml jeśli są OK, z napowietrznej znaczników:

Danych

<?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) 

Wyjście

string {} Lorem 
Ipsum 
Dolor 
4

propos Twojego komentarza:

Chcę ją wykorzystać do konfiguracji. Wiele aplikacji wymyśla własny język konfiguracji. Chcę tego uniknąć. Ale json i ConfigParser nie spełniają mnie. Json nie zezwala na ciągi znaków z ciągami znaków (tylko \ n), a narzędzie ConfigParser nie zezwala na zagnieżdżanie danych o strukturach . Następna rzecz, której mi brakuje: Walidacja (ale jest to inny temat).

Są tam 3 główne opcje masz ConfigParser, ConfigObj lub YAML (PyYAML) - każdy z ich indywidualnych zalet i wad. Wszystkie 3 są lepsze niż JSON dla twojego przypadku użycia, tj. Pliku konfiguracyjnego.

Teraz dalej, który z nich jest lepszy, zależy od tego, co dokładnie chcesz przechowywać w pliku conf.


ConfigObj - do konfiguracji i walidacji (Twój use-case):

ConfigObj jest bardzo prosty w użyciu następnie YAML (również ConfigParser). Obsługuje domyślne wartości i typy, a także obejmuje sprawdzanie poprawności (ogromny plus przez ConfigParser).

An Introduction to ConfigObj

Podczas sprawdzania poprawności, każdy z członków w specyfikacji są sprawdzane i poddawane są procesowi, który konwertuje wartości do określonego typu. Brakujące wartości, które mają wartości domyślne, zostaną wypełnione w, a sprawdzanie poprawności zwraca wartość True, aby wskazać powodzenie lub słownik z elementami, którym nie udało się sprawdzić poprawności. Indywidualne kontrole i konwersje są wykonywane przez funkcje, a dodanie własnej funkcji sprawdzania jest bardzo proste.

P.S. Tak, pozwala na wartości wieloliniowe.


Pomocne linki:

A Brief ConfigObj Tutorial

ConfigObj 5 Introduction and Reference


Istnieją stałe SO odpowiedzi dostępne na porównaniu YAML vs ConfigParser vs ConfigObj:

What's better, ConfigObj or ConfigParser?

ConfigObj/ConfigParser vs. using YAML for Python settings file


0

Nie jestem pewien, czy mam rozumieć swoje pytanie poprawnie, ale ty nie pytając o coś takiego?

my_config = { 
    "text": """first line 
second line""" 
} 

print my_config 
+0

Jaki jest format danych? Pokazujesz źródło Pythona. To była już odpowiedź użytkownika "uchwyt". – guettli

+0

@guettli Och, zgadza się, mój punkt był dokładnie taki sam, jak użytkownik "uchwyt". – BPL

1

Jeśli używasz Pythona 2, naprawdę myślę, że json może zrobić to, czego potrzebujesz. Można zrzucić i json obciążenie podczas dekodowania i kodowania go 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 

Wyjście:

{"text": "first line 
second line"} 

{u'text': u'first line\nsecond line'} 

Tak, można użyć dekodowany ciąg edytować JSON, znaki nowej linii włączone, a gdy czytając to, po prostu koduj za pomocą łańcucha znaków, aby odzyskać słownik.