0

Python でコマンドの出力を解析する必要があります。コマンドは次のようなものを返します

A:
        2 bs found
        3 cs found
B:
        1 a found
        3 bs found
C:
        1 c found
        D:
                2 es found
                3 fs found

出力で次のことができる必要があります。

アクセス a.bs found ba found. 見つかった cdes など。

このパイソンはどうすればいいですか?これを行うのに最適なデータ構造は何ですか?

この演習の目標は、コマンドを 10 秒ごとに実行し、変更内容の差分を特定することです。

4

2 に答える 2

2

別の解決策は、入力文字列を既存のライブラリが読み取れるものに直接変換することです。この特定のデータは、YAML に適しているように見えます。

この場合re.sub('( +)([1-9]+) ([a-z]).+', '\\1\\3 : \\2', allcontent)、「2 cs found」タイプの行を pyYAML が理解できる key:value マッピングに書き換えます。正確には、「2 cs found」という形式は「c : 2」になります。

結果?

A:
        b : 2
        c : 3
B:
        a : 1
        b : 3
C:
        c : 1
        D:
                e : 2
                f : 3

を実行yaml.load(newcontent)すると、次の python データ構造が返されます。

{'A': {'b': 2, 'c': 3},
 'B': {'a': 1, 'b': 3},
 'C': {'D': {'e': 2, 'f': 3}, 'c': 1}}

これは、以前のコメントでの私の提案と一致します。json を好む場合 (Python にはjsonモジュールが付属しています)、この戦略を適応させて代わりに JSON を生成するのは非常に簡単です。

于 2013-05-17T01:51:20.410 に答える
0

これは一般的な解析の問題であるため、「解析」タグが必要です。

この種の状況での通常の解決策は、a) インデントと b) 現在解析されている構造のリストを追跡することです。b は、単一の空の dict を含むリストとして始まります。curparsing = [{}]

すべての入力行をループします。例えば:

with open('inputfilename','r') as f:
    for line in f:
        # code implementing the below rules.
  • 行が空白の場合 ( if not line.strip():)、それを無視して次の行に進む ( continue)

  • インデント レベルが減少した場合は、現在解析中のリストの一番上の項目 (つまり ) を削除する必要がありますcurparsing.pop()。複数の減少が検出された場合は、複数の項目を上位から削除する必要があります。

  • で先頭のインデントを取り除きますline=line.lstrip()

  • 「:」が行にある場合、サブディクショナリが見つかりました。キー(':' の左側の部分)を読み取り、インデント レベルを上げ、新しい辞書を作成し、現在のリストの一番上にある辞書に挿入します。次に、新しく作成した辞書をリストに追加します。

  • if line[0] in '123456789':その後、「[count] [character]s found」というレポートを見つけました。正規表現を使用して、カウントと文字を見つけることができますm = re.match('([1-9]+) ([a-z])'); count, character = m.groups(); count = int(count). 次に、これを現在のリストの一番上にある辞書に保存します。curparsing[-1][character] = count

それだけです。行をループしてこれらのルールを各行に適用するだけで、最後にcurparsing[0]解析されたドキュメントが含まれます。

于 2013-05-17T01:25:45.567 に答える