2017-03-10 203 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 

即我现在只是放弃保留任何非空间评论。

相关问题