Bonjour,

Nous avons des besoins d'analyse de fichiers (texte, des logs en fait) évolutif.
Suivant les besoins, il nous faut donc y chercher tel ou tel valeur à tel ou tel emplacement.
J'ai fait rapidement (... contrainte immédiate ^^) un petit script python qui va analyser les fichiers présents (je zappe les spécifications sur ce point, pas d'importance ici) et récupérer 3 ou 4 groupes (enregistrés dans un fichier texte ou une bdd).

Afin qu'il soit facilement utilisable et adaptable, la regex est configuré via un fichier .ini (par lot/type/source de fichiers).

Le script va donc récupérer la liste de fichier suivant le paramétrage et pour chaque va vérifier le pattern souhaité ligne par ligne en récupérant le cas échéant les données. Jusque là, tout va bien.
Seulement, nous pouvons avoir plusieurs recherches nécessaire. Avec des milliers de fichiers (voir plus!), faire plusieurs passes est hors de question!
Le fichier de configuration permet donc d'indiquer plusieurs regex (avec un nombre de groupe de capture variable suivant le besoin).

Côté script, pour chaque ligne je compile le Regex de chaque groupe de configuration présent et traire avec celui-ci.
Sauf que...
J'ai testé avec une regex, puis deux, et le temps de traitement double! Oui, j'ai deux regex, mais le parcours des fichiers hors traitement regex me semblait plus conséquent dans le temps global de traitement.
D'ailleurs, une première version non dymanique avait les deux regex dans le script. Et pour chaque ligne, je traitais celles-ci. Seules différences : elles étaient compilées hors boucle de lecture (et inscrite dans le python au lieu du fichier de conf). Côté résultat... moitié moins de temps (peu de différence qu'on ai une ou deux regex en fait).

Bref :
- pourquoi est-ce si lourd? L'opération "re.compile" est-elle si lourde en temps (je ne vois que ça comme explication)?
- auriez-vous des suggestions d'amélioration? Concaténer (|) les regex? Les compiler hors boucle? A votre avis, quelle est l'option la plus efficace? Sachant qu'il faudra que je gère le titre de la recherche (un par regex).

Le code actuel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
for file in list_files:  
    for line in open(file):  
        for groupe in config.sections():
            pattern = config[groupe]['Regex']
            pattern = re.compile(pattern)
            titre = config[groupe]['Nom']
            for match in re.finditer(pattern, line):
                with open(logfile, 'a') as f:
                    f.write('{};{};{};{}\n'.format(titre,match.group('Source'),match.group('Date'),match.group('Valeur'),match.group('Valeur2')))
                f.closed
Exemple de regex :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
[GROUP1]
Regex=(?P<Source>\d{5})\s*\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.*NumSerie\s(?P<Valeur>\d{5})(?P<Date>)
Nom=SN
[GROUP2]
Regex=(?P<Source>\d{5})\s*(?P<Date>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}).*Reboot.* Nouvelle valeur =(?P<Valeur>ERR|INC|NOK) 
Nom=Erreur démarrage
Je ne suis pas encore bloqué et vais continuer mes tests.
Mais si vous avez des conseils avisés, ça m'évitera de passer du temps sur un mauvais choix!
Merci!


PS : Bon, en relisant au calme, je devrais réfléchir à l'intérêt du compile si je le relance à chaque boucle...
Du coup, je penses partir sur une liste créé au départ selon la configuration, et parcourue à chaque analyse de ligne. Si ce n'est pas la meilleure solution, merci pour vos retours sinon je poursuis dans cette voie.