2016-09-02 6 views
0

内のキーと値のログを解析:は、私は次のようなシステムログを持っているのPython

{ 
    a = 1 
    b = 2 
    c = [ 
      x:1, 
      y:2, 
      z:3, 
     ] 
    d = 4 
} 

私は=分割キーと値のペアを持つ辞書オブジェクトにPythonでこれを解析します。同時に、[]で囲まれた配列も保存されます。私はこれを可能な限り一般的なものにしておきたいので、解析にはいくつかの将来のバリエーションも含まれています。

私はこれまでに試したことがあります(コードは書かれます): "="で各行をキーと値のペアに分割し、[と]の開始と終了を決めてから、値のペア。それは少しハードコードされているようだ..任意の良いアイデア?

+0

[voluptuous](https://pypi.python.org/pypi/voluptuous)に慣れておくことをお勧めします。また、キーと値のペアは、改行でカンマで区切られていませんか? –

+0

@ NathanielFord、正確にはそのフォーマット –

+0

「保存する」ということを明確にすることはできますか? –

答えて

1

これはかなり簡単にYAMLに簡素化することができます。 pip install pyyaml、そのようにように設定:我々は、最初の行では

data2 = data.replace(":", ": ").replace("=", ":").replace("[","{").replace("]","}") 

lines = data2.splitlines() 
for i, line in enumerate(lines): 
    if len(line)>0 and line[-1] in string.digits and not line.endswith(",") or i < len(lines) - 1 and line.endswith("}"): 
     lines[i] += "," 
data3 = "\n".join(lines) 
yaml.load(data3) # {'a': 1, 'b': 2, 'c': {'x': 1, 'y': 2, 'z': 3}, 'd': 4} 

説明

import string, yaml 

data = """ 
{ 
    a = 1 
    b = 2 
    c = [ 
      x:1, 
      y:2, 
      z:3, 
     ] 
    d = 4 
} 
""" 

をこの設定では、あなたのデータを解析するために、次の使用することができますいくつかの単純な置換を実行してください:

  • YAMLでは、キーと値のペアにコロンの後にスペースが必要です。だからreplace(":", ": ")で、これを保証することができます。
  • YAMLのキー/値のペアは、常にコロンで示されると、あなたのフォーマットは時々使用されているので、我々は.replace("=", ":")
  • あなたの形式は時々中括弧はYAMLで使用されるべきである角括弧を使用してを使用してコンマと等号を置き換える、等号。

    { 
        a : 1 
        b : 2 
        c : { 
          x: 1, 
          y: 2, 
          z: 3, 
         } 
        d : 4 
    } 
    

    次に、我々はforループを持っている:私たちはあなたのデータは次のようになり、この時点で.replace("[","{").replace("]","}")

を使用して固定します。これは、行が欠落している行の後にコンマを追加することになります。ループのために不足している2つの場合は、次のとおりです。 - 彼らは、数値 後に欠席している - 閉じ括弧

我々はlen(line)>0 and line[-1] in string.digitsで(最後の文字を使用して、これらの例最初にマッチした後、彼らは存在しています行は数字です)

2番目のケースはi < len(lines) - 1 and line.endswith("}")を使用して一致します。これにより、行が}で終わるかどうかがチェックされ、YAMLは最後の括弧の後にカンマを許可しないので、行が最後でないかどうかをチェックします。ループの後

、我々は持っている:有効なYAMLである

{ 
    a : 1, 
    b : 2, 
    c : { 
      x: 1, 
      y: 2, 
      z: 3, 
     }, 
    d : 4, 
} 

。残っているのはyaml.loadです。あなたは自分自身にPython dictを持っています。

何かが明確でない場合は、コメントを残してください。私は喜んで丁寧に説明します。

1

おそらくもっと良い答えがありますが、すべての辞書キーが同じインデントレベルにあることを利用します。リスト構造がちょっと変わっているので(リストと辞書の間のクロスのように思える)、改行やJSONの読み込み、あるいはそのようなことをするのは明らかな方法ではありません。ここで

は、インデントレベルに基づいてキーを解析し、実装です:

import re 

log = '''{ 
    a = 1 
    b = 2 
    c = [ 
      x:1, 
      y:2, 
      z:3, 
     ] 
    d = 4 
}''' 
log_lines = log.split('\n')[1:-1] # strip bracket lines 
KEY_REGEX = re.compile(r' [^ ]') 

d = {} 
current_pair = '' 
for i, line in enumerate(log_lines): 
    if KEY_REGEX.match(line): 
     if current_pair: 
      key, value = current_pair.split('=') 
      d[key.strip()] = value.strip() 
     current_pair = line 
    else: 
     current_pair += line.strip() 

if current_pair: 
    key, value = current_pair.split('=') 
    d[key.strip()] = value.strip() 

print(d) 

出力

{'d': '4', 'c': '[x:1,y:2,z:3,]', 'a': '1', 'b': '2'} 
+0

「保存」とはどういう意味か分かりませんでした。それは私には奇妙に思える。 –

+0

タプルとしてそれらを必要としない限り、リストにキーと値のペアのように見えるものをどのように格納するのか分かりません。それはかなり簡単ですが、明確化されていないので、私は最も一般的なことをしました。 – Karin

+0

あなたは私の答えで別の実装を提供すべきだと思いますか?私はちょうどサブディクテーションとしてそれを解析し、 "保存"はメインレベルにマージするのではなくサブレベルとして保つことを前提としていました。 –

関連する問題