2017-03-10 37 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では空白行は保持されませんでしたが、放出されたときにすべてのコメントが通過する点で改行を取り除くことで、その動作を戻すのは比較的簡単です。ruamel/yaml/emitter.py。幸いなことに、改行に続いて空白で構成される行は既に改行だけに縮小されています。基本的には、データに添付されたコメントを検索して書き直す方法を考え出す代わりに、コメントをあなたに伝えます。

私は機能をテストするためにいくつかのより多くの空のコメント行の例が含まれていました。

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) 

ができます:

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 

これはもちろん、すべてのstrip_empty_lines_write_comment「をインストール」後にデータをダンプに影響します。プログラム内でデータをダンプする必要がある場合は、空行をサブクラス化し、Emitterに基づいてStrippingEmitterをサブクラス化し、そのサブクラスを使用してStrippingRoundTripDumperRoundTripDumperruamel/yaml/dumper.pyなど)にする必要があります。

(あなたはもちろん、コードからコメントアウトデバッグ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 

つまり、私は今、スペース以外のコメントを残すことをあきらめています。

関連する問題