用python处理重复结构化文本文件

用python处理重复结构化文本文件,python,parsing,text,parser-generator,Python,Parsing,Text,Parser Generator,我有一个大的文本文件,按块结构,如: Student = { PInfo = { ID = 0001; Name.First = "Joe"; Name.Last = "Burger"; DOB = "01/01/2000"; }; School = "West High"; Address = {

我有一个大的文本文件,按块结构,如:

Student = {
        PInfo = {
                ID   = 0001;
            Name.First = "Joe";
            Name.Last = "Burger";
            DOB  = "01/01/2000";
        };
        School = "West High";
        Address = {
            Str1 = "001 Main St.";
            Zip = 12345;
        };
    };
    Student = {
        PInfo = {
            ID   = 0002;
            Name.First = "John";
            Name.Last = "Smith";
            DOB  = "02/02/2002";
        };
        School = "East High";
        Address = {
            Str1 = "001 40nd St.";
            Zip = 12346;
        };
        Club = "Football";
    };
    ....
学生区共享相同的条目,如“PInfo”、“School”和“Address”,但其中一些可能有其他条目,例如“John Smith”的“Club”信息,而“Joe Burger”则不包括这些信息。 我想做的是获取每个学生的姓名、学校名称和邮政编码,并将其存储在字典中,如

    {'Joe Burger':{School:'West High', Zip:12345}, 'John Smith':{School:'East High', Zip:12346}, ...}

作为python编程新手,我尝试打开文件并逐行分析,但它看起来太麻烦了。真实的文件比我上面发布的示例更大、更复杂。我想知道是否有更简单的方法。谢谢。这不是json,而是类似的结构。您应该能够将其重新格式化为json

  • “=”->“:”
  • 用“”引用所有键
  • “;“->”
  • 删除所有“,”,后跟“}”
  • 把它放在花括号里
  • 用json.loads解析它
  • 为此,我使用了一个接口。它允许将文本描述为语法规则,并将其解析为数组树(parse tree)。然后,您可以遍历该树以将结果保存为哈希(哈希是perl,用于python字典)或按原样使用

    我使用您的输入制作了一个工作示例:,

    希望这有帮助


    ast_traverse()
    示例:

    要解析文件,可以定义描述输入格式的语法,并使用它生成解析器

    有。例如,您可以使用将的变体中的语法作为输入,并输出Python中的记忆解析器

    要安装Grako,请运行
    pip install Grako

    以下是使用Grako风格的EBNF语法的格式语法:

    (* a file is zero or more records *)
    file = { record }* $;
    record = name '=' value ';' ;
    name = /[A-Z][a-zA-Z0-9.]*/ ;
    value = object | integer | string ;
    (* an object contains one or more records *)
    object = '{' { record }+ '}' ;
    integer = /[0-9]+/ ;
    string = '"' /[^"]*/ '"';
    
    要生成语法分析器,请将语法保存到文件中,例如,
    Structured.ebnf
    ,然后运行:

    $ grako -o structured_parser.py Structured.ebnf
    
    它创建可用于从输入中提取学生信息的
    structured_parser
    模块:

    #!/usr/bin/env python
    from structured_parser import StructuredParser
    
    class Semantics(object):
        def record(self, ast):
            # record = name '=' value ';' ;
            # value = object | integer | string ;
            return ast[0], ast[2] # name, value
        def object(self, ast):
            # object = '{' { record }+ '}' ;
            return dict(ast[1])
        def integer(self, ast):
            # integer = /[0-9]+/ ;
            return int(ast)
        def string(self, ast):
            # string = '"' /[^"]*/ '"';
            return ast[1]
    
    with open('input.txt') as file:
        text = file.read()
    parser = StructuredParser()
    ast = parser.parse(text, rule_name='file', semantics=Semantics())
    students = [value for name, value in ast if name == 'Student']
    d = {'{0[Name.First]} {0[Name.Last]}'.format(s['PInfo']):
         dict(School=s['School'], Zip=s['Address']['Zip'])
         for s in students}
    from pprint import pprint
    pprint(d)
    
    输出
    如果是
    json
    yaml
    ,则有一个模块可以非常轻松地读取该数据。我昨天问了一个类似的问题,但尚未收到任何答案-。对您的question@spade:你得到了完全不同的东西。没有任何神奇的算法可以自动地理解一个结构或图案兴。我得自己做;对不起。@DonQuestion,我清楚地看到这两个问题之间有很多相似之处,因为它们都可以表示为n元树。这些模式对人眼来说非常明显-应该可以训练机器来学习阅读。我希望有人来自编译器,甚至NLP领域s提供从嵌套结构构建泛型树的建议。在任何情况下,我无意劫持此线程,因此将到此为止。您可以尝试或其他方式为您的输入格式创建解析器。
    {'Joe Burger': {'School': u'West High', 'Zip': 12345},
     'John Smith': {'School': u'East High', 'Zip': 12346}}