Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

RegEx qui matche trop?

+1 vote

J'ai une fonction python27 qui cherche à matcher une RegEx dans un buffer:

def find_comp_lines(lines_to_parse, line_rule, verbose=False, offset=0):
    """
    Find the line occurrences in the lines_to_parse buffer, based on a regex rule.

    :param lines_to_parse: the buffer of the COMP file.
    :param line_rule: the rule corresponding to the tag you want to find.
    :param verbose: (optional) set this to True if you want to get more log.
    :param offset: (optional) give this a value to apply an offset to the returned values (useful for nested nodes).
    :type lines_to_parse: list of string
    :type line_rule: string
    :type verbose: bool
    :type offset: int
    :return: the line occurrence indexes.
    :rtype: list of int
    """
    # Init
    res_list = []

    for idx,line in enumerate(lines_to_parse):
        if verbose:
            print "line : %s ,line rule : %s " %(line,line_rule)
        if re.match(line_rule,line) is not None:
            # save line_number
            # print idx
            res_list.append(idx+offset)

    return res_list

Jusqu'à présent elle marchait très bien, j'étais heureux. Mais vla-t-y-pas qu'à ma dernière RegEx

(\t{3}Inputs\s=\s) 

construite ainsi

'(\t{' + str(n_lvl+1) + '}' + inputs_tag.replace(' ','\s') + ')'

avec n_lvl = 2 et inputs_tag = 'Inputs = ', elle me choppe toutes les occurrences de 'Inputs =' dans mon buffer (beaucoup), sans tenir compte de la consigne sur le nombre de tabulations. J'ai testé la regex dans tous les sens, dans mon code et sur le simulateur, rien à faire.

demandé 19-Sep par furankun (1,410 points)
edité 20-Sep par furankun

un exemple de chaine que ca doit trouver ?

        [...]
        CustomData = {
            Settings = {                    
                [2] = {
                    Tools = ordered() {
                        PR_amb_night_MainA = ColorCorrector {
                            Inputs = { # ne devrait pas matcher
                            },
                        },
                    },
                },
            },
        },
        Inputs = { # devrait etre le seul resultat
        },
    [...]

Si la regexp n'a pas changé et qu'elle attrape toutes les occurences, c'est que le format du fichier sur la ligne que la regexp n'aurait pas du trouver, a changé.
Genre il y a bien 3 tabulations mais elles sont plus grandes sur la ligne Inputs 4 niveau plus bas.

Ou alors le lvl a été incrémenté à ton insu et vaut plus que 3 ?

j'ai fait un test et ta regexp marche parfaitement sur la base de la string que tu as mise précédemment

#!/usr/bin/env python
# coding: utf-8
import re
p = re.compile('(\t{3}Inputs\s=\s)')

with open('test.txt') as o:
    for line in o:

        if p.match(line):
            print("trouve ", line)

affiche bien une seule fois

trouve              Inputs = {

Quand j'ouvre le fichier dans Notepad++ je n'ai pas de différences dans les tabs, et en plus c'est un format de fichier basé sur l'indentation donc je ne pense pas qu'il change en cours de route.
peut-être que j'aurais du commencer par faire un "compile", effectivement!

1 Réponse

+2 votes
 
Meilleure réponse

Pour que ça marche il faut ajouter le position anchor " ^ " au début de la RegEx:

^(\t{3}Inputs\s=\s)

Sinon le code va matcher tout ce qui inclut la RegEx de référence (3 tabs sont inclues dans 8 tabs...).
Merci à mon collègue Guido pour la solution!

répondu 20-Sep par furankun (1,410 points)
...