2011-07-25 10 views
8

chcę analizować dokumenty yaml jak na poniższymdokument Ładowanie jako surowego ciąg w YAML z PyYAML

meta-info-1: val1 
meta-info-2: val2 

--- 

Plain text/markdown content! 
jhaha 

Gdybym load_all to z PyYAML, pojawia się następujący

>>> list(yaml.load_all(open('index.yml'))) 
[{'meta-info-1': 'val1', 'meta-info-2': 'val2'}, 'Plain text/markdown content! jhaha'] 

co usiłuję aby to osiągnąć, plik yaml powinien zawierać dwa dokumenty, a drugi powinien być interpretowany jako dokument jednoliniowy, a dokładniej dowolny duży fragment tekstu z formatowaniem przecinków. Nie chcę, aby był on analizowany jako składnia YAML.

W powyższym przykładzie PyYAML zwraca drugi dokument jako pojedynczy ciąg. Ale jeśli drugi dokument ma na przykład znak : zamiast na przykład !, pojawia się błąd składni. Dzieje się tak dlatego, że PyYAML analizuje zawartość w tym dokumencie.

Czy jest sposób, w jaki mogę powiedzieć PyYAML, że drugi dokument jest zwykłym ciągiem, a nie parsowaniem?

Edytuj: Kilka doskonałych odpowiedzi tam. Podczas korzystania z cytatów lub literalnej składni rozwiązuje ten problem, chciałbym, aby użytkownicy mogli pisać tekst bez żadnych dodatkowych cruft. Tylko trzy: - (lub .) i wypisz duży fragment zwykłego tekstu. Które mogą zawierać również cytaty. Chciałbym wiedzieć, czy mogę powiedzieć PyYAML, by przeanalizował tylko jeden dokument i dał mi drugi surowiec.

Eidt 2: Tak, pomysł Adaptacja AGF jest, zamiast korzystania z try/z wyjątkiem drugiego dokumentu może być prawidłowa składnia yaml,

config_content, body_content = open(filename).read().split('\n---') 
config = yaml.loads(config_content) 
body = yaml.loads(body_content) 

Dzięki rww.

+1

Twój dokument nie jest ważny YAML –

+0

Wiem. Nie zamierzam pisać poprawnego yaml w drugim dokumencie. Chcę, aby był czytany jako surowy ciąg znaków, niezapisany jako yaml. –

Odpowiedz

5

Można zrobić

raw = open(filename).read() 
docs = [] 
for raw_doc in raw.split('\n---'): 
    try: 
     docs.append(yaml.load(raw_doc)) 
    except SyntaxError: 
     docs.append(raw_doc) 

Jeśli nie będzie mieć kontrolę nad formatem oryginalnym dokumencie.

Od docs PyYAML,

dwukrotnie cytowany jest najpotężniejszym styl i tylko styl, który można wyrazić jakąkolwiek wartość skalarna. Podwójnie cytowane skalary pozwalają na ucieczkę. Używając sekwencji ucieczki \ x ** i \ u **** możesz wyrazić dowolny znak ASCII lub Unicode.

Wygląda na to, że nie ma możliwości przedstawienia arbitralnego skalaru w analizie, jeśli nie jest on podwójnie cytowany.

+0

Tak, myślałem o tym, ale jakaś część mnie nie była zbytnio zadowolona z tego pozornie * hackowego * rozwiązania :) –

+0

http: //pyyaml.org/wiki/PyYAMLDocumentation może mieć prawdziwe rozwiązanie, ale szybkie skanowanie i wyszukiwanie nie ujawnia mi tego. – agf

+0

Tak, spędziłem z nim dobre 2 godziny zanim zapytam tutaj: –

2

Jeśli chcesz tylko uciec znak dwukropka w YAML, a następnie zamknąć go w pojedynczych lub podwójnych cudzysłowów. Możesz także wypróbować literal style dla drugiego dokumentu, który powinien być traktowany jako pojedynczy skalar.

+0

Witam Senthil, zobacz moją aktualizację. Btw, myślę, że widziałem cię kiedyś w Bangalore PyCon. Czy to ty? ;) –

+0

Cześć Shrikant, tak, to ja. :) Miło cię poznać w SO.Przy okazji, wracając do twojego pytania, zrobiłbym warunkowe obciążenie YAML w zależności od sekcji lub przeciążenie klasy obciążenia YAML. Pierwsze rozwiązanie (ładowanie warunkowo) wydaje się łatwiejsze. –

+0

Poczuj się tak samo :). Czy możesz wyjaśnić więcej na temat * warunkowo ładującego * metody? Nie sądzę, że to rozumiem. –