2017-03-10 74 views
0

我正在使用Ruamel Python庫以編程方式更新人工編輯的YAML文件。刪除Ruamel.yaml中的所有空行但不包含註釋

我有這樣的數據:事先

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

    d: 3 
    # Comment. 
    e: 4 

我不知道在哪裏的評論將會和在空行會。

我需要這個重置爲:

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

我可以從previousanswers看我怎麼可以簡單地刪除所有的意見,但我不知道怎麼看CommentToken裏面,看它是否含有我需要保留的意見。在ruamel/yaml/emitter.pyEmitter.write_comment()

回答

0

早期版本ruamel.yaml的將不保留空行,它卻是比較容易通過在要發射時,所有評論通過點剝離換行符得到該行爲了。幸運的是,由空格和換行符組成的行已經被簡化爲換行符。從本質上講,並不是搜索附加評論的數據並找出如何重寫它們,而是讓評論來找你。

我包括一些空註釋行的情況下測試功能:「安裝」 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) 

給出。如果你需要在你的程序也轉儲數據空行,那麼你需要使用該子類的子類基於EmitterStrippingEmitter,並作出StrippingRoundTripDumper(如在ruamel/yaml/dumper.pyRoundTripDumper)。

(當然你可以刪除從代碼中註釋掉調試print語句)

+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 

即我現在只是放棄保留任何非空間評論。

相關問題