1

検索してデータを抽出したい 500 ~ 600 個のファイルのグループがあります。私はpyparsingを使用しようとしていますが、成功は非常に限られています。ファイルには、(1) コメント、(2) 単純な割り当て、(3) ネストされた割り当ての 3 つしかありません。ネスティングは約 6 レベルの深さになります。

私の目標は、3 レベルのディープ フィールドで特定の値を調べ、特定の値がある場合は、同じ第 2 レベル フィールドの一部である別の第 3 レベル フィールドから値を引き出すことです。

まず、pyparse はこれを行うための適切なツールですか? そうでない場合、他の推奨事項はありますか?

ファイルのリストを作成し、それらを反復処理する方法を知っています。サンプル ファイルと、試しているコードを示します。

# TOP_OBJECT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TOP_OBJECT=
(
    obj_fmt=
    (
    obj_name="foo"
    obj_cre_date=737785182  # = Tue May 18 23:19:42 1993
    opj_data=
    (
        a="continue"
        b="quit"
    )
    obj_version=264192  # = Version 4.8.0
    )

# LEVEL1_OBJECT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    LEVEL1_OBJECT=
    (
        OBJ_part=
        (
        obj_type=1005
        obj_size=120
        )

# LEVEL2_OBJECT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        LEVEL2_OBJECT_A=
        (
            OBJ_part=
            (
            obj_type=3001
            obj_size=128
            )

            Another_part=
            (
                another_attr=
                (
                another_style=0
                another_param=2
                )
            )
        ) ### End of LEVEL2_OBJECT_A ###
# LEVEL2_OBJECT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        LEVEL2_OBJECT_B=
        (
            OBJ_part=
            (
            obj_type=3005
            obj_size=128
            )

            Another_part=
            (
                another_attr=
                (
                another_style=0
                another_param=8
                )
            )
        ) ### End of LEVEL2_OBJECT_B ###
    ) ### End of LEVEL1 OBJECT
) ### End of TOP_OBJECT ###

ファイルをダイジェストするための私のコードは次のようになります。

from pyparsing import *

def Syntax():
    comment = Group("#" + restOfLine).suppress()
    eq = Literal('=')
    lpar  = Literal( '(' ).suppress()
    rpar  = Literal( ')' ).suppress()
    num = Word(nums)
    var = Word(alphas + "_")
    simpleAssign = var +  eq
    nestedAssign = Group(lpar + OneOrMore(simpleAssign) + rpar)
    expr = Forward()
    atom = nestedAssign | simpleAssign
    expr << atom 
    expr.ignore(comment)
    return expr

def main():

    expr = Syntax()
    results = expr.parseFile( "for_show.asc" )
    print results

if __name__ == '__main__':
    main()

結果が下がらない: ['TOP_OBJECT', '=']

現在、引用符で囲まれた文字列や数字を処理していません。ネストされたリストの解析を理解しようとしているだけです。

4

1 に答える 1

1

ほとんどの場合、パーサーにいくつかのギャップがあります。現在のコードと比較して、コメントアウトされた元のコードを参照してください。

def Syntax():
    comment = Group("#" + restOfLine).suppress()
    eq = Literal('=')
    lpar  = Literal( '(' ).suppress()
    rpar  = Literal( ')' ).suppress()
    num = Word(nums)
    #~ var = Word(alphas + "_")
    var = Word(alphas + "_", alphanums+"_")
    #~ simpleAssign = var +  eq
    expr = Forward()
    simpleAssign = var +  eq + (num | quotedString)
    #~ nestedAssign = Group(lpar + OneOrMore(simpleAssign) + rpar)
    nestedAssign = var +  eq + Group(lpar + OneOrMore(expr) + rpar)
    atom = nestedAssign | simpleAssign
    expr << atom 
    expr.ignore(comment)
    return expr

これは与える:

['TOP_OBJECT',
 '=',
 ['obj_fmt',
  '=',
  ['obj_name',
   '=',
   '"foo"',
   'obj_cre_date',
   '=',
   '737785182',
   'opj_data',
   '=',
   ['a', '=', '"continue"', 'b', '=', '"quit"'],
   'obj_version',
   '=',
   '264192'],
  'LEVEL1_OBJECT',
  '=',
  ['OBJ_part',
   '=',
   ['obj_type', '=', '1005', 'obj_size', '=', '120'],
   'LEVEL2_OBJECT_A',
   '=',
   ['OBJ_part',
    '=',
    ['obj_type', '=', '3001', 'obj_size', '=', '128'],
    'Another_part',
    '=',
    ['another_attr',
     '=',
     ['another_style', '=', '0', 'another_param', '=', '2']]],
   'LEVEL2_OBJECT_B',
   '=',
   ['OBJ_part',
    '=',
    ['obj_type', '=', '3005', 'obj_size', '=', '128'],
    'Another_part',
    '=',
    ['another_attr',
     '=',
     ['another_style', '=', '0', 'another_param', '=', '8']]]]]]

expr内部のnestedAssignのOneOrMoreをGroupでラップすると

    nestedAssign = var +  eq + Group(lpar + OneOrMore(Group(expr)) + rpar)

、ネストされた割り当てを繰り返すと、より良い構造が得られると思います。

['TOP_OBJECT',
 '=',
 [['obj_fmt',
   '=',
   [['obj_name', '=', '"foo"'],
    ['obj_cre_date', '=', '737785182'],
    ['opj_data', '=', [['a', '=', '"continue"'], ['b', '=', '"quit"']]],
    ['obj_version', '=', '264192']]],
  ['LEVEL1_OBJECT',
   '=',
   [['OBJ_part',
     '=',
     [['obj_type', '=', '1005'], ['obj_size', '=', '120']]],
    ['LEVEL2_OBJECT_A',
     '=',
     [['OBJ_part',
       '=',
       [['obj_type', '=', '3001'], ['obj_size', '=', '128']]],
      ['Another_part',
       '=',
       [['another_attr',
         '=',
         [['another_style', '=', '0'], ['another_param', '=', '2']]]]]]],
    ['LEVEL2_OBJECT_B',
     '=',
     [['OBJ_part',
       '=',
       [['obj_type', '=', '3005'], ['obj_size', '=', '128']]],
      ['Another_part',
       '=',
       [['another_attr',
         '=',
         [['another_style', '=', '0'], ['another_param', '=', '8']]]]]]]]]]]

また、最初に投稿されたコードにはタブが含まれていましたが、価値があるよりも問題が多く、4 スペースのインデントを使用する方がよいことがわかりました。

于 2013-01-05T21:23:28.497 に答える