2017-03-10 3 views
0

Ruamel Python 라이브러리를 사용하여 사람이 편집 한 YAML 파일을 프로그래밍 방식으로 업데이트하고 있습니다.Ruamel.yaml의 모든 비어있는 줄 제거하기

--- 
a: 
    b: '1' 
    c: "2" 

    d: 3 
    # Comment. 
    e: 4 

나도 몰라 사전에 빈 줄이 될 것입니다 경우 코멘트가 될 것이다 :

는이 같은 데이터를 가지고있다. 나는 단순히 모든 주석을 제거 할 수 방법 previousanswers에서 볼 수

--- 
a: 
    b: '1' 
    c: "2" 
    d: 3 
    # Comment. 
    e: 4 

하지만 나는 그것이이 포함되어 있는지 확인하기 위해 CommentToken 내부를 들여다하는 방법을 모른다 :

나는이를 재설정해야 내가 지켜야 할 의견.

답변

0

이전 버전의 ruamel.yaml은 빈 줄을 보존하지 않았지만 모든 주석이 통과 할 때 줄 바꿈을 제거하여 해당 동작을 다시 얻는 것이 상대적으로 쉽습니다 (Emitter.write_comment() : ruamel/yaml/emitter.py). 운 좋게도 줄 바꿈 문자 다음에 줄 바꿈 문자로 구성된 행은 이미 줄 바꿈 문자로 축소되었습니다. 본질적으로, 데이터에 첨부 된 주석을 검색하고 다시 작성하는 방법을 알아내는 대신 주석을 사용자에게 제공합니다. strip_empty_lines_write_comment를 "설치"후 물론

a: 
    b: '1' 
    # comment followed by empty lines 
    c: "2" 
    d: 3 
    # Comment. 
    e: 4 
    # empty lines followed by comment 
    f: 5 
    # comment between empty lines 
    g: |+ 
    an empty line within a multi-line literal 

    with a trailing empty line that is not stripped 

    h: 6 
# final top level comment 

이 의지에 영향을 미치는 모든 데이터를 덤프 :

import sys 
import ruamel.yaml 

yaml_str = """\ 
--- 
a: 
    b: '1' 
    # comment followed by empty lines 


    c: "2" 

    d: 3 
    # Comment. 
    e: 4 


    # empty lines followed by comment 
    f: 5 

    # comment between empty lines 

    g: |+ 
    an empty line within a multi-line literal 

    with a trailing empty line that is not stripped 

    h: 6 

# final top level comment 
""" 

# rename the comment writer 
ruamel.yaml.emitter.Emitter.write_comment_org = ruamel.yaml.emitter.Emitter.write_comment 


# define your own comment writer that calls the orginal if the comment is not empty 
def strip_empty_lines_write_comment(self, comment): 
    # print('{:02d} {:02d} {!r}'.format(self.column, comment.start_mark.column, comment.value)) 
    comment.value = comment.value.replace('\n', '') 
    if comment.value: 
     self.write_comment_org(comment) 

# install 
ruamel.yaml.emitter.Emitter.write_comment = strip_empty_lines_write_comment 

data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True) 
ruamel.yaml.round_trip_dump(data, sys.stdout) 

이 제공 :

나는 기능을 테스트하기 위해 좀 더 빈 주석 행의 경우를 포함했다. 프로그램에서 데이터 을 덤프하려면 빈 줄이 필요하고 Emitter을 기반으로 StrippingEmitter을 서브 클래스 화하고 서브 클래스를 사용하여 StrippingRoundTripDumper ( RoundTripDumperruamel/yaml/dumper.py과 같이)으로 만듭니다.

내가 그것을 물어 그것은 구체적으로 문제가 해결되지

+0

언제나처럼 당신의 도움에 감사드립니다. 불행히도, 나는 때때로 빈 줄을 지켜야하기 때문에 이런 식으로 할 수는 없다. 내가 실제로 가지고있는 문제는 Ruamel.yaml이 하나의 YAML 파일에서 다른 YAML 파일로 데이터를 복사 할 때 일부 컨텍스트에서 원하지 않는 빈 줄을 추가한다는 것입니다. 왜 그런지 이해하지 못했습니다. 어쨌든 내 도구가 변경되는 데이터의 주석과 간격을 제어 할 수 있어야하지만 내 도구를 사용하지 않는 사람들이 서식을 변경하지 않아야합니다. –

+0

주석에 대한 일반적인 제어가 중요하지 않으며 또 다른 웜 깡통을 열 것입니다. 도구 사용자가 댓글을 달 수 있도록 하시겠습니까? 이러한 주석을 유지하지 않거나 유지하고 싶지 않은 경우 사용자가 업데이트 한 데이터의 주석을 비교적 쉽게 패치 할 수 있습니다. – Anthon

0

(당신은 물론 코드에서 주석 디버깅 인쇄 문을 제거 할 수 있습니다)하지만 가치가 무엇인지, 나는이 함께 결국 :

data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True) 

space, no_space = map(lambda x: 
    [None, None, ruamel.yaml.tokens.CommentToken(x, \ 
     ruamel.yaml.error.CommentMark(0), None), None], ['\n\n', '\n']) 

for key in data['a'].ca.items: 
    data['a'].ca.items[key] = no_space 

last = data['a'].keys()[-1] 
data['a'].ca.items[last] = space 

즉, 저는 지금 비 공간 주석을 유지하는 것을 포기합니다.

관련 문제