ply - python parse text




Traitement du fichier texte structuré à plusieurs reprises avec python (2)

ce n'est pas JSON, mais similaire structuré. vous devriez être capable de le reformater en JSON.

  1. "=" -> ":"
  2. citez toutes les touches avec '"'
  3. ";" -> ","
  4. supprimer tous les "," qui sont suivis d'un "}"
  5. le mettre entre accolades
  6. analyser avec json.loads

J'ai un gros fichier texte structuré en blocs comme:

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";
    };
    ....

Les blocs Etudiants partagent les mêmes entrées comme "PInfo", "École" et "Adresse", mais certains d'entre eux peuvent avoir des entrées supplémentaires, telles que les informations "Club" pour "John Smith" qui ne sont pas incluses pour "Joe Burger" . Ce que je veux faire est d'obtenir le nom, le nom de l'école et le code postal de chaque étudiant et de les stocker dans un dictionnaire, comme

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

Étant nouveau pour la programmation python, j'ai essayé d'ouvrir le fichier et de l'analyser ligne par ligne, mais il semble si lourd. Et le vrai fichier est assez volumineux et plus compliqué que l'exemple que j'ai posté plus haut. Je me demande s'il existe un moyen plus simple de le faire. Merci d'avance.


Pour analyser le fichier, vous pouvez définir une grammaire qui décrit votre format d'entrée et l'utiliser pour générer un analyseur.

Il y a beaucoup de parseurs de langage en Python . Par exemple, vous pouvez utiliser Grako qui prend les grammaires dans une variante de EBNF en entrée, et édite des mémoseurs de PEG en Python.

Pour installer Grako, exécutez pip install grako .

Voici la grammaire pour votre format en utilisant la syntaxe de la syntaxe EBNF de Grako:

(* 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 = '"' /[^"]*/ '"';

Pour générer un analyseur, enregistrez la grammaire dans un fichier, par exemple, Structured.ebnf et exécutez:

$ grako -o structured_parser.py Structured.ebnf

Il crée structured_parser module structured_parser qui peut être utilisé pour extraire les informations de l'étudiant à partir de l'entrée:

#!/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)

Sortie

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




parser-generator