4

次の形式の構成ファイルがあります。

protocol sample_thread {
    { AUTOSTART 0 }
    { BITMAP thread.gif }
    { COORDS {0 0} }
    { DATAFORMAT {
        { TYPE hl7 }
        { PREPROCS {
            { ARGS {{}} }
            { PROCS sample_proc }
        } }
    } } 
}

実際のファイルにはこれらの正確なフィールドがない可能性があり、解析する前にデータの構造をパーサーに説明する必要はありません。

他の構成ファイルパーサーを探しましたが、この構文のファイルを受け入れることができるものは見つかりませんでした。

このようなファイルを解析できるモジュールを探していますが、何か提案はありますか?

興味のある方は、問題のファイルはQuovadxCloverleafによって生成されました。

4

8 に答える 8

11

pyparsingは、このような迅速で単純な構文解析に非常に便利です。最低限は次のようになります。

import pyparsing
string = pyparsing.CharsNotIn("{} \t\r\n")
group = pyparsing.Forward()
group << pyparsing.Group(pyparsing.Literal("{").suppress() + 
                         pyparsing.ZeroOrMore(group) + 
                         pyparsing.Literal("}").suppress()) 
        | string

toplevel = pyparsing.OneOrMore(group)

次のように使用します。

>>> toplevel.parseString(text)
['protocol', 'sample_thread', [['AUTOSTART', '0'], ['BITMAP', 'thread.gif'], 
['COORDS', ['0', '0']], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', 
[['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]]

そこから、必要に応じてより洗練されたものにすることができます(文字列から個別に数値を解析したり、特定のフィールド名を探したりするなど)。上記はかなり一般的で、文字列("{"と"}"を除く空白以外の文字として定義されます)と{}で区切られた文字列のリストを探します。

于 2009-06-15T14:35:14.420 に答える
2

ブライアンのpyparsingソリューションを別のステップとして、Dictクラスを使用して、この形式の準デシリアライザーを作成できます。

import pyparsing

string = pyparsing.CharsNotIn("{} \t\r\n")
# use Word instead of CharsNotIn, to do whitespace skipping
stringchars = pyparsing.printables.replace("{","").replace("}","")
string = pyparsing.Word( stringchars )
# define a simple integer, plus auto-converting parse action
integer = pyparsing.Word("0123456789").setParseAction(lambda t : int(t[0]))
group = pyparsing.Forward()
group << ( pyparsing.Group(pyparsing.Literal("{").suppress() +
    pyparsing.ZeroOrMore(group) +
    pyparsing.Literal("}").suppress())
    | integer | string )

toplevel = pyparsing.OneOrMore(group)

sample = """
protocol sample_thread {
    { AUTOSTART 0 }
    { BITMAP thread.gif }
    { COORDS {0 0} }
    { DATAFORMAT {
        { TYPE hl7 }
        { PREPROCS {
            { ARGS {{}} }
            { PROCS sample_proc }
        } }
    } } 
    }
"""

print toplevel.parseString(sample).asList()

# Now define something a little more meaningful for a protocol structure, 
# and use Dict to auto-assign results names
LBRACE,RBRACE = map(pyparsing.Suppress,"{}")
protocol = ( pyparsing.Keyword("protocol") + 
             string("name") + 
             LBRACE + 
             pyparsing.Dict(pyparsing.OneOrMore(
                pyparsing.Group(LBRACE + string + group + RBRACE)
                ) )("parameters") + 
             RBRACE )

results = protocol.parseString(sample)
print results.name
print results.parameters.BITMAP
print results.parameters.keys()
print results.dump()

プリント

['protocol', 'sample_thread', [['AUTOSTART', 0], ['BITMAP', 'thread.gif'], ['COORDS', 

[0, 0]], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]]
sample_thread
thread.gif
['DATAFORMAT', 'COORDS', 'AUTOSTART', 'BITMAP']
['protocol', 'sample_thread', [['AUTOSTART', 0], ['BITMAP', 'thread.gif'], ['COORDS', [0, 0]], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]]
- name: sample_thread
- parameters: [['AUTOSTART', 0], ['BITMAP', 'thread.gif'], ['COORDS', [0, 0]], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]
  - AUTOSTART: 0
  - BITMAP: thread.gif
  - COORDS: [0, 0]
  - DATAFORMAT: [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]

pyparsingを使えばさらに速くなると思います。

-ポール

于 2009-08-29T13:57:04.017 に答える
1

pythonでスクリプトを簡単に記述して、それをpython dictに変換できます。形式は、階層的な名前と値のペアのように見えます。問題はCoards {0 0}のようです。ここで、{0 0}は名前と値のペアではありませんが、そのようなケースが他にどのような形式であるかを知っている人のためのリストです。あなたの最善の策は、その形式の仕様を用意し、それを読み取るための簡単なPythonスクリプトを作成することだと思います。

于 2009-06-15T14:18:36.940 に答える
1

足りない質問だと思うものに答えてみます...

構成ファイルにはさまざまな形式があります。*.iniやapacheconfigなどのよく知られた形式があります。これらには、多くのパーサーが使用できる傾向があります。

次に、カスタム形式があります。それがあなたのように見えます(それはあなたと私がこれまでに見たことがない明確に定義された形式である可能性がありますが、それが何であるかがわかるまでは実際には問題ではありません)。

私はこれが由来するソフトウェアから始めて、これらのファイルをロード/生成できるプログラミングAPIを持っているかどうかを確認します。明らかなことがない場合は、Quovadxに電話してください。誰かがすでにこの問題を解決している可能性があります。

それ以外の場合は、おそらく自分でパーサーを作成する必要があります。

サンプルが完全な例を代表していると仮定すると、この形式のパーサーを作成することはそれほど難しくありません。これは値の階層であり、各ノードには値または値の子階層のいずれかを含めることができます。値にパーサーを含めることができる基本的な型を定義すると、非常に単純な構造になります。

Lex / Flexのようなもの、または選択した言語の単純なパーサーを使用して、これをかなり迅速に書くことができます。

于 2009-06-15T13:58:51.293 に答える
1

構成ファイルはJSONと非常によく似ています(ほとんどの場合、すべての「{」と「}」を「[」と「]」に置き換えます)。ほとんどの言語にはJSONパーサー(PHP、Ruby、Pythonなど)が組み込まれており、そうでない場合は、それを処理するために使用できるライブラリがあります。

構成ファイルの形式を変更できない場合は、すべてのファイルの内容を文字列として読み取り、すべての「{」および「}」文字を任意の方法で置き換えることができます。次に、文字列をJSONとして解析でき、設定が完了します。

于 2009-06-15T14:44:06.647 に答える
0

チーズショップで少し検索しましたが、あなたの例に役立つものは何も見つかりませんでした。[]ページと、この特定のパーサーを確認してください(構文は少し似ています)。これはあなたがあなた自身を書くのを助けるべきだと思います。

于 2009-06-15T14:04:44.480 に答える
0

LEXとYACCを調べてください。少し学習曲線がありますが、どの言語のパーサーも生成できます。

于 2009-06-15T14:13:24.113 に答える
-2

たぶん、あなたはあなたの設定をxmlファイルに変換する簡単なスクリプトを書いて、それからlxml、Beatuful Soupまたは他のものを使うだけでそれを読むことができますか?また、コンバーターは、たとえばPyParsingまたは正規表現を使用できます。

于 2009-06-15T13:58:00.453 に答える