IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Expression reguliere sur n lignes


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut Expression reguliere sur n lignes
    Bonsoir ,

    Je souhaiterais effectuer un contrôle syntaxique via les expressions régulières sur une variable de n lignes.

    pex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def maFonction(field, format):
     	valide=True
    	if re.match(format,field):
    		valide=True
    	else:
    		valide=False
    	return valide
     
    champ="Bonjours\na\ntous"
    format="[a-zA-Z]"
    maFonction(champ,format)
    Je souhaiterai pouvoir via cette fonction écrire une expression régulière qui me permette d'effectuer un contrôle de syntaxe sur tous les mots de la chaine.

    Merci de votre contribution

    Lagdu

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Quel genre de contrôle syntaxique ?
    Le code que tu donnes (en supposant que maFonction est en fait check_field_format) va seulement vérifier que le premier caractère de la chaîne est une lettre, rien de plus.

    Comme tu parles de faire un contrôle sur tous les mots de la chaîne, si tu travailles mot par mot, tu peux pas simplement faire un split() et contrôler chaque mot ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Salut divedee ,

    En fait le type de contrôle syntaxique est peut important. Le problème auquel je fait face est que :

    J'ai écris plusieurs expressions régulières pour faire un contrôle sur de chaines de caractères.

    Ses chaines de caractères sont généralement écrites sur une ligne, mais quelques une sont écrites sur 1 a n lignes.

    Concrètement je doit par exemple vérifier qu'une chaine comporte:
    4 caractères en majuscule puis deux slashs puis une valeur décimale de 10 caractères maximum deux slash puis éventuellement 5 lignes supplémentaires de 0 a 35 caractères.
    Ce qui me donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ("([A-Z]{4})//([0-9,]{10}//([a-zA-Z0-9/-?:().,'+{} ]{0,35})$")
    Malheureusement je ne sais pas comment exprimer le fait que la dernière partie puisse être écrite sur 1 à n lignes.

    Tu viens de me mettre sur une piste en utilisant éventuellement un split() , mais je souhaitais si possible me restreindre a l'utilisation d'expression régulière pour m'éviter d'alourdir mes traitements sur les chaines.

    J'espère avoir été plus clair dans mes explications.

    PS : effectivement je me suis trompé de nom lors de l'appel de la fonction . C'est bien maFonction(champ,format) qui est appelée j'édite le message précédent.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Quelqu'un connaissant mieux les expressions régulières passera peut-être, mais en attendant, as-tu essayé qqch comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "([A-Z]{4})//([0-9,]{10}//(([a-zA-Z0-9/-?:().,'+{} ]{0,35})\n){0,5}$"
    Regarde aussi l'option MULTILINE, qui change la signification de $.
    Mais si les données contiennent plusieurs fois le motif, cela risque de poser un problème, car la deuxième partie du motif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ([a-zA-Z0-9/-?:().,'+{} ]{0,35})
    matche aussi le début d'une nouvelle apparition du motif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ([A-Z]{4})//([0-9,]{10}//
    Toute chaîne correspondant à la première partie du motif correspond également à la seconde. Il faut qu'il y ait un moyen de distinguer une ligne supplémentaire de l'instance courante du motif avec le début d'une nouvelle instance du motif.

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Maintenant que tu as précisé ta demande, on peut essayer d'y répondre.
    Mais ça ne m'a pas empêché de m'intéresser au sujet. Je l'ai étudié un peu en me disant qu'à défaut de pouvoir donner une réponse à une question mal posée, je pouvais essayer de trouver les questions possibles sur le sujet...
    Alors voilà le fruit de mes cogitations.


    J'ai d'abord vérifié qu'effectivement on peut examiner par regex une chaine comportant des caractères '\n':

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fruits = \
    'noix,noisette\nbanane,citron\ngroseille,fraise,framboise\ncassis,\
    mûre\nlitchi,avocat,goyave\n'
    print 'recherche1 =',[re.search('.*fraise.*\n.*cassis.*',fruits).group()]
    donne
    recherche1 = ['groseille,fraise,framboise\ncassis,m\xfbre']
    NB: les crochets autour de re.search(...).group() permettent d'avoir un affichage de tous les caractères y compris les caractères spéciaux comme '\n' et '\xfb' et non pas de les faire jouer en tant que caractères spéciaux.

    On voit que '.*' devant 'fraise' fait prendre en compte les caractères devant 'fraise' par la regex mais qu'elle ne prend pas ceux avant '\n' parce que le point '.' ne matche pas avec '\n'. Sauf si on écrit explicitement '\n' dans la regex.
    Documentation:
    «Dans le mode par défaut, '.' matche n'importe quel caractère sauf un newline. Si le drapeau DOTALL est spécifié, le point '.' matche tous les caractères y compris les newline.»

    Et en effet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fruits = \
    'noix,noisette\nbanane,citron\ngroseille,fraise,framboise\ncassis,\
    mûre\nlitchi,avocat,goyave\n'
    print 'recherche2 =',[re.search('.*fraise.*\n.*cassis.*',fruits,re.DOTALL).group()]
    donne
    recherche2 = ['noix,noisette\nbanane,citron\ngroseille,fraise,framboise\ncassis,m\xfbre\nlitchi,avocat,goyave\n']
    -----------------------------------------------------------------------

    Ensuite, j'ai regardé des trucs un peu plus compliqués.

    Question 1: peut on par exemple, avec les regex, extraire d'un fichier les lignes comportant un certain motif mais sans examiner explicitement les lignes l'une après l'autre avec un for ligne in fichier:, et sans mettre non plus le fichier en liste ? C'est à dire d'appliquer un algorithme de regex sur le fichier considéré sous sa forme native de chaine de caractères.


    Pour une recherche simple, le for ligne in f est le plus simple. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fruits = 'noix,noisette\nbanane,citron\ngroseille,fraise,framboise\n\
    cassis,mûre\nlitchi,avocat,goyave\n'
    f = open('fichier fruits','w')
    f.write(fruits)
    f.close()
     
    f = open('fichier fruits')
    lignes = [ln for ln in f if 'a' in ln]
    f.close()
    print 'lignes de fruits avec a =\n',lignes
    donne
    lignes de fruits avec a =
    ['banane,citron\n', 'groseille,fraise,framboise\n', 'cassis,m\xfbre\n', 'litchi,avocat,goyave\n']
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    f = open('fichier fruits')
    lignes = [ln for ln in f if 'goyave' in ln]
    f.close()
    print 'lignes de fruits avec goyave =',lignes
    donne
    lignes de fruits avec goyave =
    ['litchi,avocat,goyave\n']



    Mais dès que c'est un peu plus compliqué ,c'est moins simple (si, si):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    f = open('fichier fruits')
    lignes = [ln for ln in f if set(['fraise','cassis']).intersection(set(ln.split(',')))!=set([])]
    f.close()
    print 'lignes fraises-cassis =',lignes
    donne bien
    lignes fraise-cassis =
    ['groseille,fraise,framboise\n', 'cassis,m\xfbre\n']




    Pour ce qui suit, on est obligé d'abandonner le recours à une list comprehension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    f = open('fichier fruits')
    selec = []
    for ln in f:
        for mot in ln.split(','):
            if 'a' in mot and 'o' in mot:
                selec.append(ln)
                break
    f.close()
    print "\nlignes avec mots contenant a la fois'o' et 'a' au moyen de for ln in f: et d'un if ="
    print selec
    donne
    lignes avec mots contenant a la fois'o' et 'a' au moyen de for ln in f: et d'un if =
    ['groseille,fraise,framboise\n', 'litchi,avocat,goyave\n']
    Si on utilise une list comprehension, on ne peut pas mettre le break (en tous cas je ne sais pas le faire; si quelqu'un sait comment procéder, je suis intéressé) qui est nécessaire pour éviter de sélectionner deux fois des lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    f = open('fichier fruits')
    soloc = [ln for ln in f for mot in ln.split(',') if ('a' in mot and 'o' in mot)]
    f.close()
    print "\nlignes avec mots contenant a la fois'o' et 'a' (incorrecte)"
    print "au moyen de for ln in f: et d'un if dans une list comprehension ="
    print soloc
    donne
    lignes avec mots contenant a la fois'o' et 'a' (incorrecte)
    au moyen de for ln in f: et d'un if dans une list comprehension =
    ['groseille,fraise,framboise\n', 'litchi,avocat,goyave\n', 'litchi,avocat,goyave\n']


    Avec une regex, c'est déjà plus condensé et exact, même si ça ne parait pas plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    f = open('fichier fruits')
    silic = []
    for ln in f:
        if re.search('(^|,)[a-z]*((a[a-z]+o)|(o[a-z]+a))[a-z]*(,|$)',ln):
            silic.append(ln)
    f.close()
    print "\nlignes avec mots contenant a la fois 'o' et 'a' au moyen de for ln in f: et d'une regex ="
    print silic
    donne bien aussi
    lignes avec mots contenant a la fois 'o' et 'a' au moyen de for ln in f: et d'une regex =
    ['groseille,fraise,framboise\n', 'litchi,avocat,goyave\n']
    NB: ici les signes '^' et '$' matchent le début et la fin de chaque ligne.




    Si on fait appel à toutes les possibilités des regex, c'est à dire cette fois à finditer() , ça devient aussi simple qu'une list comprehension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    f = open('fichier fruits')
    print "\nlignes avec mots contenant a la fois 'o' et 'a' au moyen de la fonction finditer() ="
    print [m.group() for m in re.finditer('^([a-z]+,)*[a-z]*((a[a-z]+o)|(o[a-z]+a))[a-z]*(,[a-z]+)*$',f.read(),re.M)]
    f.close()
    donne
    lignes avec mots contenant a la fois 'o' et 'a' au moyen de la fonction finditer() =
    ['groseille,fraise,framboise', 'litchi,avocat,goyave']
    >>>
    On obtient même les lignes sans le caractères line break '\n' terminal.

    NB: du fait que finditer() est utilisé au lieu de search(), la regex doit être différente pour que le matching se fasse sur la totalité d'une "ligne" afin que la chaine qui matche, donnée par m.group() , soit cette "ligne" et non pas seulement le mot avec 'o' et 'a' qui fait l'essentiel du matching.
    NB2: finditer() n'examine pas des lignes, il examine une chaine f.read() d'un seul bloc dans laquelle les signes '^' et '$' permettent de repérer le début et la fin de chacune des portions qui donnent les lignes lors d'un affichage de f.read(). Pour que '^' et '$' matchent avec "juste après '\n'" et "juste avant '\n'" , il faut ajouter le drapeau re.MULTILINE comme argument de la fonction finditer(). Il oblige "^" et "$" à matcher autour de '\n' et pas seulement aux extrémités d'une chaine.


    -------------------------------------------------

    Deuxième question: comment se passent les détections par regex sur plusieurs lignes ? C'est à dire comment se passent les choses pour des cas plus sophistiqués que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    re.search('.*fraise.*\n.*cassis.*','noix,noisette\nbanane,citron\n\
    groseille,fraise,framboise\ncassis,mûre\nlitchi,avocat,goyave\n') ?
    J'ai résumé des choses dans le code suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    import re
     
    f = open('fifi','w')
    f.write('oceans\t\t\t361126222 km2\n')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('terres emergees\t\t148939063 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('asie\t\t\tt43810582 km2\n')
    f.write('amerique\t\t42189120 km2\n')
    f.write('afrique\t\t\t30206704 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('antarctique\t\t14200000 km2\n')
    f.write('ocean arctique\t\t14090000 km2\n')
    f.write('europe\t\t\t10180000 km2\n')
    f.close()
     
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
    print '---------------------------------------1'
    for m in re.finditer('^ocean.+ique',ch):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+ique',ch):
        print [m.group()]
    print '---------------------------------------2'
    for m in re.finditer('^ocean.+ique',ch,re.S):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+ique',ch,re.S):
        print [m.group()]
    print '---------------------------------------3'
    for m in re.finditer('^ocean.+ique',ch,re.M):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+ique',ch,re.M):
        print [m.group()]
    print '---------------------------------------4'
    for m in re.finditer('^ocean.+ique',ch,re.M|re.S):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+ique',ch,re.M|re.S):
        print [m.group()]
    print '\n'
    print '---------------------------------------5'
    for m in re.finditer('^ocean.+?ique',ch,re.S):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+?ique',ch,re.S):
        print [m.group()]
    print '---------------------------------------6'
    for m in re.finditer('^ocean.+?ique',ch,re.M):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+?ique',ch,re.M):
        print [m.group()]
    print '---------------------------------------7'
    for m in re.finditer('^ocean.+?ique',ch,re.M|re.S):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+?ique',ch,re.M|re.S):
        print [m.group()]
     
    print '---------------------------------------8'
    for m in re.finditer('^ocean.+(ique)?',ch):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+(ique)?',ch):
        print [m.group()]
    print '---------------------------------------9'
    for m in re.finditer('^ocean.+(ique)?',ch,re.M):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+(ique)?',ch,re.M):
        print [m.group()]
    print '---------------------------------------10'
    for m in re.finditer('^ocean.+?(ique)?',ch,re.M):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+?(ique)?',ch,re.M):
        print [m.group()]
    print '---------------------------------------11'
    for m in re.finditer('^ocean.+?(ique)?$',ch,re.M):
        print 'AAAA'+m.group()+'ZZZZ'
    for m in re.finditer('^ocean.+?(ique)?$',ch,re.M):
        print [m.group()]
    print '---------------------------------------'
    qui donne
    ---------------------------------------1
    pattern = ^ocean.+ique
    ---------------------------------------2
    pattern = ^ocean.+ique
    AAAAoceans 361126222 km2
    ocean pacifique 166241700 km2
    terres emergees 148939063 km2
    ocean atlantique 106000000 km2
    ocean indien 75000000 km2
    asie t43810582 km2
    amerique 42189120 km2
    afrique 30206704 km2
    ocean antarctique 20327000 km2
    antarctique 14200000 km2
    ocean arctiqueZZZZ
    ['oceans\t\t\t361126222 km2\nocean pacifique\t\t166241700 km2\nterres emergees\t\t148939063 km2\nocean atlantique\t106000000 km2\nocean indien\t\t75000000 km2\nasie\t\t\tt43810582 km2\namerique\t\t42189120 km2\nafrique\t\t\t30206704 km2\nocean antarctique\t20327000 km2\nantarctique\t\t14200000 km2\nocean arctique']
    ---------------------------------------3
    pattern = ^ocean.+ique
    AAAAocean pacifiqueZZZZ
    AAAAocean atlantiqueZZZZ
    AAAAocean antarctiqueZZZZ
    AAAAocean arctiqueZZZZ
    ['ocean pacifique']
    ['ocean atlantique']
    ['ocean antarctique']
    ['ocean arctique']
    ---------------------------------------4
    pattern = ^ocean.+ique
    AAAAoceans 361126222 km2
    ocean pacifique 166241700 km2
    terres emergees 148939063 km2
    ocean atlantique 106000000 km2
    ocean indien 75000000 km2
    asie t43810582 km2
    amerique 42189120 km2
    afrique 30206704 km2
    ocean antarctique 20327000 km2
    antarctique 14200000 km2
    ocean arctiqueZZZZ
    ['oceans\t\t\t361126222 km2\nocean pacifique\t\t166241700 km2\nterres emergees\t\t148939063 km2\nocean atlantique\t106000000 km2\nocean indien\t\t75000000 km2\nasie\t\t\tt43810582 km2\namerique\t\t42189120 km2\nafrique\t\t\t30206704 km2\nocean antarctique\t20327000 km2\nantarctique\t\t14200000 km2\nocean arctique']


    ---------------------------------------5
    pattern = ^ocean.+?ique
    AAAAoceans 361126222 km2
    ocean pacifiqueZZZZ
    ['oceans\t\t\t361126222 km2\nocean pacifique']
    ---------------------------------------6
    pattern = ^ocean.+?ique
    AAAAocean pacifiqueZZZZ
    AAAAocean atlantiqueZZZZ
    AAAAocean antarctiqueZZZZ
    AAAAocean arctiqueZZZZ
    ['ocean pacifique']
    ['ocean atlantique']
    ['ocean antarctique']
    ['ocean arctique']
    ---------------------------------------7
    pattern = ^ocean.+?ique
    AAAAoceans 361126222 km2
    ocean pacifiqueZZZZ
    AAAAocean atlantiqueZZZZ
    AAAAocean indien 75000000 km2
    asie t43810582 km2
    ameriqueZZZZ
    AAAAocean antarctiqueZZZZ
    AAAAocean arctiqueZZZZ
    ['oceans\t\t\t361126222 km2\nocean pacifique']
    ['ocean atlantique']
    ['ocean indien\t\t75000000 km2\nasie\t\t\tt43810582 km2\namerique']
    ['ocean antarctique']
    ['ocean arctique']
    ---------------------------------------8
    pattern = ^ocean.+(ique)?
    AAAAoceans 361126222 km2ZZZZ
    ['oceans\t\t\t361126222 km2']
    ---------------------------------------9
    pattern = ^ocean.+(ique)?
    AAAAoceans 361126222 km2ZZZZ
    AAAAocean pacifique 166241700 km2ZZZZ
    AAAAocean atlantique 106000000 km2ZZZZ
    AAAAocean indien 75000000 km2ZZZZ
    AAAAocean antarctique 20327000 km2ZZZZ
    AAAAocean arctique 14090000 km2ZZZZ
    ['oceans\t\t\t361126222 km2']
    ['ocean pacifique\t\t166241700 km2']
    ['ocean atlantique\t106000000 km2']
    ['ocean indien\t\t75000000 km2']
    ['ocean antarctique\t20327000 km2']
    ['ocean arctique\t\t14090000 km2']
    ---------------------------------------10
    pattern = ^ocean.+?(ique)?
    AAAAoceansZZZZ
    AAAAocean ZZZZ
    AAAAocean ZZZZ
    AAAAocean ZZZZ
    AAAAocean ZZZZ
    AAAAocean ZZZZ
    ['oceans']
    ['ocean ']
    ['ocean ']
    ['ocean ']
    ['ocean ']
    ['ocean ']
    ---------------------------------------11
    pattern = ^ocean.+?(ique)?$
    AAAAoceans 361126222 km2ZZZZ
    AAAAocean pacifique 166241700 km2ZZZZ
    AAAAocean atlantique 106000000 km2ZZZZ
    AAAAocean indien 75000000 km2ZZZZ
    AAAAocean antarctique 20327000 km2ZZZZ
    AAAAocean arctique 14090000 km2ZZZZ
    ['oceans\t\t\t361126222 km2']
    ['ocean pacifique\t\t166241700 km2']
    ['ocean atlantique\t106000000 km2']
    ['ocean indien\t\t75000000 km2']
    ['ocean antarctique\t20327000 km2']
    ['ocean arctique\t\t14090000 km2']
    ---------------------------------------
    Cas 1:
    '^' matche uniquement le début de ch.
    le point ne matche pas avec '\n'.
    '^ocean.+ique' commence au début de ch et s'arrête avant le premier '\n'. Comme il n'y a pas la sous-chaine 'ique' requise dans la portion 'oceans\t\t\t361126222 km2\' , la regex ne matche rien.

    Cas 2:
    '^' matche uniquement le début de ch.
    La présence du drapeau re.S force le point à matcher avec les newlines '\n'.
    Comme '+' est glouton ( documentation: «The "*", "+", and "?" qualifiers are all greedy; they match as much text as possible.»), la RE '.+' va aussi loin que possible avant de s'arrêter devant une succession 'ique' qui est requise: '.+' va donc jusqu'au 'ique' de l'avant-dernière ligne. Même les lignes qui ne contiennent pas 'ique' sont aussi prises dans le match.
    D'ailleurs, comme '.+' s'arrête au dernier 'ique', la superficie de cette ligne n'est pas dans la chaine matchée: il y a un hic.

    Cas 3:
    Comme en 1, la regex ne matche toujours rien dans la première portion allant du début de ch au premier '\n'.
    Comme il n'y a pas de drapeau re.S (abbréviation de re.DOTALL), le point dans '.+' ne matche pas avec le premier newline '\n' et empêche la regex d'explorer au delà du premier newline.
    Cependant la présence du drapeau re.M fait matcher '^' au début de ch et juste après tous les '\n'. Donc re.M permet à '^' d'explorer la suite, et il y a détection des portions comprises entre tous les '\n' suivants, ce qui correspond aux lignes, et la regex matche quand il y a 'ique'.

    Cas 4:
    c'est le cas 2 + cas 3 additionnés: le caractère glouton de '.+' rend inopérante la faculté de '^' de matcher après les newlines. La regex va d'abord jusqu'au dernier 'ique', requis, puis '^' fait explorer la dernière ligne dans laquelle il n'y a pas de 'ique'.
    Le réultat est le mêm que dans le cas 2.

    Cas 5:
    si on rend '.+' non glouton en modifiant son comportement par un '?' (documentation: «Adding "?" after the qualifier makes it perform the match in non-greedy or minimal fashion; as few characters as possible will be matched.» il s'agit de *?, +?, ?? ), la regex consomme la chaine seulement tant qu'elle ne rencontre pas le premier 'ique'. Comme re.S permet au point de passer le premier '\n', la regex peut aller jusqu'au 'ique' de la deuxième ligne. Elle matche donc du début de la première ligne qui ne contient pourtant pas de 'ique' jusqu'au 'ique' de la deuxième ligne.
    Comme il n'y a pas de re.M pour autoriser '^' à matcher aprés le deuxième '\n', la regex n'explore pas plus loin.

    Cas 6:
    '.+' est rendu frugal par '?', ce qui ne change strictement rien par rapport au cas 3: l'absence de drapeau re.S empêche la regex d'explorer au delà du premier newline.
    Mais comme en 3, re.M permet à la regex d'explorer toutes les lignes.
    Le résultat est donc identique au cas 3.

    Cas 7:
    C'est le cas 4 + '.+?' rendu frugal.
    - '.+?' grignote la chaine, en passant les '\n' gràce à re.S, jusqu'à rencontrer un 'ique' requis
    C'est ainsi que les lignes sans 'ique' comme 'oceans\t\t\t361126222 km2\n' , 'ocean indien\t\t75000000 km2\n' , 'asie\t\t\tt43810582 km2\n' , 'amerique\t\t42189120 km2\n' qui sont parcourues par le grignotage participent aux résultats.
    - Par contre '^ocean' et re.M permettent à la regex d'explorer toutes les portions commençant par 'ocean' après '\n', et les lignes 'terres emergees\t\t148939063 km2\n' , 'afrique\t\t\t30206704 km2\n' , 'antarctique\t\t14200000 km2\n' et 'europe\t\t\t10180000 km2\n' sont exclues des portions matchantes.

    Cas 8:
    La regex part du début de la chaine et bute sur le premier '\n' mais le (ique)? est facultatif. À la différence du cas 1, l e résultat est donc la première ligne.

    Cas 9:
    La regex part de chaque début de ligne commençant par 'ocean', car re.M permet à '^' de matcher après chaque newline et à la regex d'explorer tout le fichier.
    (ique)? est facultatif mais '.+' ne bute que sur le premier '\n' rencontré. Le résultat est donc formé de toutes les lignes commençant par 'ocean', dans leur entier.

    Cas 10:
    (ique)? est facultatif et la RE '.+?' est '.+' rendue flemmarde par '?'
    '.+?' s'arrête donc 1 caractère après 'ocean', c'est à dire dès qu'il a trouvé le caractère obligatoire spécifié par '+'.

    Cas 11:
    C'est un cas intéressant à examiner.
    C'est le cas 10 auquel on a juste ajouté le caractère '$' qui matche juste avant les '\n'. Sa présence oblige '.+?' à parcourir des caractères jusqu'à rencontrer un newline '\n'. On peut noter que la regex passe dessus 'ique' grâce à '.+?' et non grâce à (ique)?, sinon '.+?' ne pourrait pas continuer pour les caractères situés au delà de 'ique'.
    Le cas 10 se trouve modulé et on se retrouve avec comme résultat l'ensemble des lignes entières contenant 'ocean'.

    Bon, on peut s'amuser comme ça à l'infini.

    -----------------------------------------------------------------

    Troisième question: y a-t-il d'autres avantages que la concision à utiliser les regex et finditer() au lieu d'une boucle sur un fichier ?

    Il y a au moins la vitesse, le recours à finditer() en list comprehension a tendance à être 28% plus rapide que les autres méthodes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    import re
    from timeit import Timer
     
    f = open('fifi','w')
    f.write('oceans\t\t\t361126222 km2\n')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('terres emergees\t\t148939063 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('asie\t\t\tt43810582 km2\n')
    f.write('amerique\t\t42189120 km2\n')
    f.write('afrique\t\t\t30206704 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('antarctique\t\t14200000 km2\n')
    f.write('ocean arctique\t\t14090000 km2\n')
    f.write('europe\t\t\t10180000 km2\n')
    f.close()
     
    def simpl():
        f = open('fifi','r')
        fh = f.readlines()
        f.close()
        loo = []
        for ln in fh:
            if re.search('^ocean.+$',ln):
                loo.append(ln)
        return loo
     
    def litfh():
        f = open('fifi','r')
        fh = f.readlines()
        f.close()
        return [ ln for ln in fh if re.search('^ocean.+$',ln) ]
     
    def diter():
        f = open('fifi','r')
        ch = f.read()
        f.close()
        return [ m.group() for m in re.finditer('^ocean.+$',ch,re.M) ]
     
    iterations = 12
    tsimpl = Timer('simpl()','from __main__ import simpl').repeat(iterations, 1000)
    tlitfh = Timer('litfh()','from __main__ import litfh').repeat(iterations, 1000)
    tditer = Timer('diter()','from __main__ import diter').repeat(iterations, 1000)
     
    print simpl()
    print "avec if re.search('^ocean.+$',ln): loo.append(ln)"
    for u in tsimpl:
        print round(u,4),
    print '  secondes'
    print 'moyenne = ',round(sum(tsimpl)/iterations,4)
    print '\n'
    print litfh()
    print "avec [ ln for ln in fh if re.search('^ocean.+$',ln) ]"
    for u in tlitfh:
        print round(u,4),
    print '  secondes'
    print 'moyenne = ',round(sum(tlitfh)/iterations,4)
    print '\n'
    print diter()
    print "avec [ m.group() for m in re.finditer('^ocean.+$',ch,re.M) ]"
    for u in tditer:
        print round(u,4),
    print '  secondes'
    print 'moyenne = ',round(sum(tditer)/iterations,4)
    print '\n'
    ['oceans\t\t\t361126222 km2\n', 'ocean pacifique\t\t166241700 km2\n', 'ocean atlantique\t106000000 km2\n', 'ocean indien\t\t75000000 km2\n', 'ocean antarctique\t20327000 km2\n', 'ocean arctique\t\t14090000 km2\n']
    avec if re.search('^ocean.+$',ln): loo.append(ln)
    0.5868 0.5768 0.6136 0.7969 0.5868 0.6043 0.61 0.6453 0.7049 0.5889 0.5814 0.5797 secondes
    moyenne = 0.6229


    ['oceans\t\t\t361126222 km2\n', 'ocean pacifique\t\t166241700 km2\n', 'ocean atlantique\t106000000 km2\n', 'ocean indien\t\t75000000 km2\n', 'ocean antarctique\t20327000 km2\n', 'ocean arctique\t\t14090000 km2\n']
    avec [ ln for ln in fh if re.search('^ocean.+$',ln) ]
    0.5778 0.6064 0.5801 0.5754 0.7579 0.5729 0.582 0.5908 0.581 0.5888 0.5772 0.5764 secondes
    moyenne = 0.5972


    ['oceans\t\t\t361126222 km2', 'ocean pacifique\t\t166241700 km2', 'ocean atlantique\t106000000 km2', 'ocean indien\t\t75000000 km2', 'ocean antarctique\t20327000 km2', 'ocean arctique\t\t14090000 km2']
    avec [ m.group() for m in re.finditer('^ocean.+$',ch,re.M) ]
    0.4703 0.5238 0.4036 0.4032 0.4028 0.4059 0.4052 0.4019 0.404 0.4035 0.4057 0.4025 secondes
    moyenne = 0.4194
    -------------------------------------------------

    Quatrième question: différences d'usage entre '^' , '$' et '\n' dans une regex.

    '^' et '$' sont bivalents tandis que '\n' est rarement présent en tête de fichier, '\n' est diversement présent à la fin d'un fichier et '\A' et '\Z' ne s'appliquent qu'aux extrémités d'un string.
    '^' et '$' sont donc plus pratiques que (\n|\A) et (\n|\Z).
    Si '$' n'existait pas, (\n|\Z) serait indispensable dans toutes le regex destinées à détecter des lignes dans une chaine.

    Si par exemple on veut vérifier que toutes les lignes d'un fichier commencent par un nom d'océan contenant la lettre 'i':

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    import re
     
     
    f = open('fifi','w')
    f.write('tous les oceans existants\t361126222 km2\n')
    f.write('ocean pacifique\t\t\t166241700 km2\n')
    f.write('ocean atlantique\t\t106000000 km2\n')
    f.write('ocean indien\t\t\t75000000 km2\n')
    f.write('ocean antarctique\t\t20327000 km2\n')
    f.write('ocean arctique\t\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
    print '[ch] =\n',[ch]
    print '\nch =\n',ch
    print
    print '================================================================================'
     
    pat = "ocean.+i.+(\Z|\n)"
    for m in re.finditer(pat,ch):
        print m.group()
    for m in re.finditer(pat,ch):
        print [m.group()]
    print '-----------------------------------------'
    pat = "(\A|\n)ocean.+i.+(\Z|\n)"
    for m in re.finditer(pat,ch):
        print m.group()
    for m in re.finditer(pat,ch):
        print [m.group()]
    print '-----------------------------------------'
    pat = '^ocean.+i.+$'
    for m in re.finditer(pat,ch,re.M):
        print m.group()
    for m in re.finditer(pat,ch,re.M):
        print [m.group()]
    print '-----------------------------------------'
    [ch] =
    ['tous les oceans existants\t361126222 km2\nocean pacifique\t\t\t166241700 km2\nocean atlantique\t\t106000000 km2\nocean indien\t\t\t75000000 km2\nocean antarctique\t\t20327000 km2\nocean arctique\t\t\t14090000 km2']

    ch =
    tous les oceans existants 361126222 km2
    ocean pacifique 166241700 km2
    ocean atlantique 106000000 km2
    ocean indien 75000000 km2
    ocean antarctique 20327000 km2
    ocean arctique 14090000 km2

    ================================================================================
    oceans existants 361126222 km2

    ocean pacifique 166241700 km2

    ocean atlantique 106000000 km2

    ocean indien 75000000 km2

    ocean antarctique 20327000 km2

    ocean arctique 14090000 km2
    ['oceans existants\t361126222 km2\n']
    ['ocean pacifique\t\t\t166241700 km2\n']
    ['ocean atlantique\t\t106000000 km2\n']
    ['ocean indien\t\t\t75000000 km2\n']
    ['ocean antarctique\t\t20327000 km2\n']
    ['ocean arctique\t\t\t14090000 km2']
    -----------------------------------------

    ocean pacifique 166241700 km2


    ocean indien 75000000 km2


    ocean arctique 14090000 km2
    ['\nocean pacifique\t\t\t166241700 km2\n']
    ['\nocean indien\t\t\t75000000 km2\n']
    ['\nocean arctique\t\t\t14090000 km2']
    -----------------------------------------
    ocean pacifique 166241700 km2
    ocean atlantique 106000000 km2
    ocean indien 75000000 km2
    ocean antarctique 20327000 km2
    ocean arctique 14090000 km2
    ['ocean pacifique\t\t\t166241700 km2']
    ['ocean atlantique\t\t106000000 km2']
    ['ocean indien\t\t\t75000000 km2']
    ['ocean antarctique\t\t20327000 km2']
    ['ocean arctique\t\t\t14090000 km2']
    -----------------------------------------
    Le pattern "ocean.+i.+(\Z|\n)" fait trouver la première ligne OK alors qu'elle ne l'est pas.
    Si on cherche à ajouter (\A|\n) dans la regex pour éliminer cette erreur (deuxième pattern "(\A|\n)ocean.+i.+(\Z|\n)" ), alors il apparait une autre erreur:
    une fois qu'un '\n' est consommé par (\Z|\n) , il n'est plus disponible pour (\A|\n) dans l'examen de la ligne suivante, ce qui fait que l'examen saute la détection des lignes 'ocean atlantique\t\t106000000 km2\n' et 'ocean antarctique\t\t20327000 km2\n'.
    Le troisiéme pattern '^ocean.+i.+$' donne satisfaction.
    De plus l'usage de '^' et '$' permet aussi de se retrouver avec des lignes propres, sans '\n'.

  6. #6
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    -----------------------------------------------------------

    Cinquième question: peut faire d'un seul coup avec une regex une vérification de l'ensemble des lignes d'un fichier, sans faire de for ligne in fichier: ou de mise en liste ?

    Yes.
    D'abord il faut utiliser match() pour faire une détection à partir du début du fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    import re
     
    f = open('fifi','w')
    f.write('tous les oceans existan\t\t361126222 km2\n')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch],'\n'
    print 'avec pattern =',r'((^ocean.+ique)+)','\n'
    m = re.match('((^ocean.+ique)+)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
     
     
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\
    ttern =',r'((^ocean.+ique)+)','\n'
    m = re.match('((^ocean.+ique)+)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
    ----------------------------------------
    [ch] =
    ['tous les oceans existan\t\t361126222 km2\nocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean indien\t\t75000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2']

    avec pattern = ((^ocean.+ique)+)

    >>>>>-- au moins une ligne non conforme --<<<<<<<
    -----------------------------------------
    [ch] =ttern = ((^ocean.+ique)+)

    ('ocean pacifique', 'ocean pacifique')
    ['ocean pacifique']
    -- fichier OK --

    Dans le premier cas, la première ligne 'tous les oceans existan\t\t361126222 km2\n' fait foirer la vérification.
    Dans le deuxième cas, après avoir enlevé cette ligne, le fichier est trouvé OK mais c'est une illusion: en regardant ce que donnent print m.groups() et print [m.group()] , on voit que le match ne va que jusqu'à 'ocean pacifique' de la première ligne.

    Il faut modifier la regex parce qu'il est obligatoire que chaque ligne soit vérifiée dans son entier et que la liaison de toutes les lignes par (...)+ fasse bien une vérification de l'ensemble des lignes. Mais pour cela on est obligé de mettre '\n', sinon avec '$' la regex s'arrête avant le '\n' de la première ligne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch],'\n'
    print 'avec pattern =',r'((^ocean.+ique.+$)+)','\n'
    m = re.match('((^ocean.+ique.+$)+)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
     
     
     
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch],'\n'
    print 'avec pattern =',r'((^ocean.+ique.+\n)+)','\n'
    m = re.match('((^ocean.+ique.+\n)+)',ch,re.M)
    if m:
        print m.groups()
        print [m.group(1)]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
    -----------------------------------------
    [ch] =
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean indien\t\t75000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2']

    avec pattern = ((^ocean.+ique.+$)+)

    ('ocean pacifique\t\t166241700 km2', 'ocean pacifique\t\t166241700 km2')
    ['ocean pacifique\t\t166241700 km2']
    -- fichier OK --
    -----------------------------------------
    [ch] =
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean indien\t\t75000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2']

    avec pattern = ((^ocean.+ique.+\n)+)

    ('ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\n', 'ocean atlantique\t106000000 km2\n')
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\n']
    -- fichier OK --
    Ce n'est pas suffisant: il y a un matching des deux premières lignes qui fait déclarer le fichier OK alors qu'il y a une ligne 'ocean indien\t\t75000000 km2\n' qui ne repecte pas ce qui est requis. Ce n'est pas un matching partiel qu'on veut. On veut que le matching commence au début de la chaine et soit valable jusqu'au bout de la chaine.
    Pour obtenir cela il faut ajouter '\Z'.
    Avec '\Z', on arrive bien cette fois à distinguer un fichier avec une mauvaise ligne d'un fichier entièrement correct:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean indien\t\t75000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2\n')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch],'\n'
    print 'avec pattern =',r'(((^ocean.+ique.+\n)+)\Z)','\n'
    m = re.match('(((^ocean.+ique.+\n)+)\Z)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
     
     
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2\n')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch],'\n'
    print 'avec pattern =',r'((^ocean.+ique.+\n)+\Z)','\n'
    m = re.match('((^ocean.+ique.+\n)+\Z)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
    -----------------------------------------
    [ch] =
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean indien\t\t75000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2\n']

    avec pattern = (((^ocean.+ique.+\n)+)\Z)

    >>>>>-- au moins une ligne non conforme --<<<<<<<
    -----------------------------------------
    [ch] =
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2\n']

    avec pattern = ((^ocean.+ique.+\n)+\Z)

    ('ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2\n', 'ocean arctique\t\t14090000 km2\n')
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2\n']
    -- fichier OK --
    Reste à pouvoir qualifier un fichier de OK même si sa dernière ligne ne comporte pas de '\n' à sa fin, donc à la fin du fichier. Il faut en fait déplacer le '\Z' à l'intérieur de chaque test de ligne en le mettant dans une alternative '\n|\Z'.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch],'\n'
    print 'avec pattern =',r'((^ocean.+ique.+\n)+\Z)','\n'
    m = re.match('((^ocean.+ique.+\n)+\Z)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
     
     
     
     
     
    f = open('fifi','w')
    f.write('ocean pacifique\t\t166241700 km2\n')
    f.write('ocean atlantique\t106000000 km2\n')
    f.write('ocean antarctique\t20327000 km2\n')
    f.write('ocean arctique\t\t14090000 km2')
    f.close()
     
    f = open('fifi','r')
    ch = f.read()
    f.close()
     
    print '-----------------------------------------'
    print '[ch] =\n',[ch]
    print 'avec pattern =',r'((^ocean.+ique.+(\n|\Z))+)','\n'
    m = re.match('((^ocean.+ique.+(\n|\Z))+)',ch,re.M)
    if m:
        print m.groups()
        print [m.group()]
        print '-- fichier OK --'
    else:
        print '>>>>>--  au moins une ligne non conforme  --<<<<<<<'
    Et ça marche ! :
    -----------------------------------------
    [ch] =
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2']

    avec pattern = ((^ocean.+ique.+\n)+\Z)

    >>>>>-- au moins une ligne non conforme --<<<<<<<
    -----------------------------------------
    [ch] =
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2']
    avec pattern = ((^ocean.+ique.+(\n|\Z))+)

    ('ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2', 'ocean arctique\t\t14090000 km2', '')
    ['ocean pacifique\t\t166241700 km2\nocean atlantique\t106000000 km2\nocean antarctique\t20327000 km2\nocean arctique\t\t14090000 km2']
    -- fichier OK --

  7. #7
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bon, c'est pas tout ça... mais il reste ton problème à traiter.


    «4 caractères en majuscule puis deux slashs»
    cela fait:
    "[A-Z}{4}//"

    «puis une valeur décimale de 10 caractères maximum deux slash»
    cela fait:
    "\d(,\d{1,7})|(\d,\d{0,6})|(\d{2},\d{0,5})|(\d{3},\d{0,4})|(\d{4},\d{0,3})|(\d{5},\d{0,2})|(\d{6},\d{0,1})|(\d{7},)\d//"

    Si, si.
    Je n'ai pas trouvé plus court pour représenter un nombre décimal de 3 à 10 caractères, en partant de l'hypothèse qu'il a toujours au moins 2 chiffres de part et d'autre de la virgule.
    Et que cette virgule est unique.
    Parce qu'avec "[\d,]{10}" , on matche tout un tas de trucs comme "123,456789" , "123,,56704" ou ",,234,4,78". Et ça ne matche pas les nombres décimaux de moins de 10 caractères comme "12,474".

    On doit pouvoir améliorer cette horrible portion de regex.
    Pour simplifier je prends "[\d,]{3,10}" pour représenter le décimal.
    C'est à toi de préciser ce que signifie «nombre décimal à 10 caractères maximum».


    "[A-Z}{4}//[\d,]{3,10}//"
    Il n'y a pas besoin des parenthèse autour de [A-Z}{4} et de [\d,]{3,10} , sauf si tu veux en faire des groupes pour suivre leur participation à des matchings au moyen de la fonction groups().


    Ensuite, j'ai beau tourner la suite dans tous les sens, je n'arrive pas à comprendre ce signifie exactement «puis éventuellement 5 lignes supplémentaires de 0 a 35 caractères».
    Est-ce que chaque ligne supplémentaire fait 0 à 35 caractères ?
    Est-ce que 0 à 35 caractères peuvent s'étaler sur p[lusieurs lignes, 5 au maximum ?
    Est-ce qu'il y a obligatoirement un line break '\n' après "[A-Z}{4}//[\d,]{3,10}//" en cas de lignes supplémentaires, ou les caractères supplémentaires peuvent commencer juste après les deux derniers '//' ?

    Bon. Je prends la chaine "ceciestune:successionde35caracteres" et je suppose que tu veux détecter les cas suivants:

    "[A-Z]{4}//[\d,]{3,10}//"
    "[A-Z]{4}//[\d,]{3,10}//ceci"
    "[A-Z]{4}//[\d,]{3,10}//ceci\n"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\n"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\n"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\nsucce"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\nsucce\n"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\nsucce\nssionde"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\nsucce\nssionde\n"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\nsucce\nssionde\n35caracteres"
    "[A-Z]{4}//[\d,]{3,10}//ceci\nest\nune:\nsucce\nssionde\n35caracteres\n"

    Je vais chercher à partir de ça. Mais ce n'est peut être pas du tout ce que tu recherches.
    Si tu passes par ici, précise un peu ce que tu veux faire STP.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Salut eyquem et dividee

    Eyquem:

    Tout d'abord merci de t'être penché avec autant d'énergie sur mon problème hallucinant le boulot que tu as fait . Je viens juste de lire ton post qui contient une foultitude d'information, je n'ai pas le temps de le lire complètement pour le moment mais je vais regarder en détail ce soir.
    Je te tire mon chapeau

    J'ai décidément du mal a exprimer mon problème précisément. Donc je vais te montrer directement un exemple de ce que je cherche a valider.

    ex:
    ABCD//0,12345678//Ici il peut y avoir 35 caractères (ligne1)
    Ici aussi (ligne2)
    Ici aussi (ligne3)
    Ici aussi (ligne4)
    Ici aussi (ligne5)
    Ici il ne peut plus rien y avoir. (ligne6)

    Voila a quoi correspond ces 5 lignes supplémentaires de 0 a 35 caractères.
    Il faut considérer la ligne qui contient ABCD//0,123456789//... Comme la ligne 1, puis chaque retour chariot comme une ligne supplémentaire.
    Celles si sont optionnelles mais des lors qu'elles sont la elle doivent passer par un contrôle syntaxique.

    Est-ce que chaque ligne supplémentaire fait 0 à 35 caractères ?
    Oui chacune de ces lignes fait bien de 0 a 35 caractères et même plus elles subissent strictement le même contrôle syntaxique. Je parle bien sur du contrôle syntaxique de 0 a 35 caractères car ensuite les 4 lettres en Majuscule et la valeur décimale de 10 caractères max n'a pas lieu d'être.

    Est-ce que 0 à 35 caractères peuvent s'étaler sur plusieurs lignes, 5 au maximum ?
    Non chaque ligne peut avoir de 0 a 35 caractères maximum. Ceci sur 5 lignes au maximum.

    Est-ce qu'il y a obligatoirement un line break '\n' après "[A-Z}{4}//[\d,]{3,10}//" en cas de lignes supplémentaires, ou les caractères supplémentaires peuvent commencer juste après les deux derniers '//' ?
    Les 35 caractères peuvent démarrer, juste après les deux derniers slashs.


    Concernant ton ER sur les valeurs décimales de 10 caractères maximum. Et bien ça va te paraitre étrange mais elles est trop pointue pour moi. J'ai juste besoin d'isoler pour le moment grossièrement les mauvaises syntaxes puis je traite séparément les différent cas:
    Le cas ou il y a plusieurs virgules , le cas ou il n'y a pas de partie entière, le cas ou il n'y a pas de virgule, le cas ou il y a plus de 10 caractères (la virgule comptant comme un caractère aussi) ... car j'ai des codes de retour différent et précis a renvoyer dans ces cas de figure. En tout cas elle me sera toujours utile celle ci .

    Dividee :

    Je me suis penché sur les solution que tu m'a proposé je n'ai rien réussi a obtenir de concluant. J'ai essayé avec le \n placé un peut partout sans résultat. L'option MULTILINE semblait être la solution a mon problème mais je n'ai pour le moment pas réussit a m'en servir correctement.
    Je suis jeune développeur dans mon premier projet pro et je suis a la bourre comme c'est pas possible. Je n'avait ni fait de python ni d'ER avant la semaine dernière donc j'ai du mal a m'adapter rapidement a ses infos. Je vais essayer de trouver comment l'utiliser quand j'aurais le temps cad jamais.

    Toute chaîne correspondant à la première partie du motif correspond également à la seconde. Il faut qu'il y ait un moyen de distinguer une ligne supplémentaire de l'instance courante du motif avec le début d'une nouvelle instance du motif.
    J'ai du mal a comprendre le sens de cette phrase .

    De mon coté je creuse aussi sur la doc pour trouver une solution a mon pblm mais rien de concluant pour le moment je tiendrais au courant si il ya a la moindre info utile. Mais vous allez tellement vite dans la recherche c'est hallucinant.

    Voila j'espère avoir été encore plus clair et n'hésitez pas a me demander pour de plus amples informations.
    Et encore merci de mettre autant d'énergie et de temps sur ce problème.

    Lagdu

  9. #9
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    J'ai trouvé le principe à mettre en œuvre pour construire la regex mais il me manque quelque chose pour aboutir.

    «Il faut considérer la ligne qui contient ABCD//0,123456789//... Comme la ligne 1, puis chaque retour chariot comme une ligne supplémentaire.
    Celles si sont optionnelles mais des lors qu'elles sont la elle doivent passer par un contrôle syntaxique.»

    Ce n'est pas suffisant comme explication.
    En fait , tu n'as toujours pas répondu à la question de dividee, qu'il a posée dès le tout début:
    «Quel genre de contrôle syntaxique ?»

    Au passage, je ne crois pas que le terme "optionnelles" convienne car si on considère une ligne1 en plein milieu du fichier, elle est nécessairement suivie d'autres lignes.

    Qu'est ce que tu recherches sur les 5 lignes ?

    Est-ce que tu cherches la plus longue succession de caractères appartenant à ton ensemble s'étendant à partir de la ligne1 sur plusieurs lignes (jusqu'à 5) ?

    Est-ce que tu cherche à détecter les groupes de 5 lignes consécutives dans lesquelles il apparait les caractères de l'ensemble défini, quel que soit leur position, leur contigüité et leur continuité depuis le début de ligne 1?

    L'objectif recherché détermine évidemment la façon dont on va faire s'allumer la regex, donc la façon dont on la construit.
    Sans le connaître, on ne peut pas avancer.

    Par exemple, avec
    Y = un caractère de ton ensemble
    x = un caractère n'étant pas dans ton ensemble
    si tu as

    Cas 1:
    ligne1 [A-Z]{4}//\d,\d{1,8}//YYYYYYYYYYYYY\n
    ligne2 YYYYYYYYYYYYYYxxxxxYYxYYYYY\n
    ligne3 xxxxxYYYYYYYYYYxx\n
    ligne4 xxxxxxxxYYxxxxxxxxxxxx\n
    ligne5 xxxxxxxYYYYYYYYxxxxxxx\n

    Cas 2:
    ligne1 [A-Z]{4}//\d,\d{1,8}//YYYYYYYYYYYYY\n
    ligne2 YYYYYYYYYYYYYY\n
    ligne3 YYYYYYYxxxxxx\n
    ligne4 xxxxxxxxxxxxxxxxxxxx\n
    ligne5 xxxxxxxxxxxxxx\n

    tu cherches à détecter quoi et tu fais quoi après l'analyse ?

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Mon but en terme général était de trouver une ER me permettant de faire un contrôle syntaxique su 1 a n lignes.

    «Quel genre de contrôle syntaxique ?»
    Dans le cas précis que j'énonce sur le forum je souhaite simplement vérifier que la partie qui suit les deux derniers slashs si elle existe ne contienne pas plus de 35 caractères ET si il y a des lignes supplémentaires qu'elles aussi ne fassent pas plus de 35 caractères. Peut importe le type de caractères contenus.

    Car dans l'absolu je cherche une manière d'exprimer le fait qu'une ER contrôle 1 a n lignes.

    Au passage, je ne crois pas que le terme "optionnelles" convienne car si on considère une ligne1 en plein milieu du fichier, elle est nécessairement suivie d'autres lignes.
    Si car les lignes qui suivent AAAA//0,12345678// sont optionnelles cela veut simplement dire que a la suite de ce format il peut y avoir 35 caractères puis un retour a la ligne 35 autres caractères ect 5 fois :

    ABCD//0,12345678//(35 caractères optionnels)
    (35 caractères optionnels)
    (35 caractères optionnels)
    (35 caractères optionnels)
    (35 caractères optionnels)

    De plus il ne faut pas se soucier du reste du fichier, il faut considérer qu'un match est appelé dans une fonction qui prend en paramètre la string qui contient les lignes a analyser et l'ER qu'il me reste a construire ce qui donnerais pex :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import re
    def maFonction(field, format):
    	valide=True
    	if re.match(format,field):
    		valide=True
    	else:
    		valide=False
    	return valide
     
    champ="AAAA//0,12345678//35 carateres\n35 autres caracteres\nECT..."
    format="[Mon ER]"
    maFonction(champ,format)
    En appelant cette fonction dans cet exemple je souhaiterais avoir un code de retour True

    Qu'est ce que tu recherches sur les 5 lignes ?
    Je recherche juste a vérifier qu'il n'y ait pas plus de 35 caractères.

    Est-ce que tu cherches la plus longue succession de caractères appartenant à ton ensemble s'étendant à partir de la ligne1 sur plusieurs lignes (jusqu'à 5) ?
    Non je ne cherche pas a faire un contrôle aussi aboutit pour le moment.

    Est-ce que tu cherche à détecter les groupes de 5 lignes consécutives dans lesquelles il apparait les caractères de l'ensemble défini, quel que soit leur position, leur contigüité et leur continuité depuis le début de ligne 1?
    Non il faut considérer que le contrôle se fait sur 5 ligne des la première ligne.

    tu cherches à détecter quoi et tu fais quoi après l'analyse ?
    Si on trouve plus de 35 caractères à la suite des derniers // et au début des 4 lignes suivantes le message est considéré comme erroné.


    Je pensait ne pensait pas que cette questions allait soulever autant d'interrogations. Je tente de me familiariser avec les Er et ce premier type de contrôle avait pour but de me permettre d'analyser n lignes via un unique modèle d'ER.

  11. #11
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bon, les choses s'éclairent.

    «Mon but en terme général...»
    «Dans le cas précis que j'énonce sur le forum je souhaite simplement ...»
    «Car dans l'absolu je cherche une manière d'exprimer ...»
    «De plus il ne faut pas se soucier du reste du fichier, il faut considérer qu'un match est appelé dans une fonction qui prend en paramètre la string qui contient les lignes a analyser et l'ER»
    «l'ER qu'il me reste a construire ce qui donnerais pex :
    »
    «En appelant cette fonction dans cet exemple ...»


    Je n'avais pas compris que tu mélanges à la fois un objectif de trouver une procédure générale (d'où l'imprécision de la formule "contrôle syntaxique") et des considérations relatives à un exemple applicatif destiné à rendre concret la procédure, cet exemple gardant cependant un caractère si général qu'il a fait illusion sur sa réelle difficulté, qui est plusieurs échelons en dessous de ce que je croyais.
    J'ai bien fait de te demander des précisions avant de proposer la regex compliquée que j'avais trouvée comme réponse à un problème que j'avais fini par imaginer être celui, bien plus simple, que tu envisages en réalité pour le moment !

    En fait aussi bien ton objectif général que ton exemple applicatif sont simples. Je me permets d'apporter tout de suite des modifications à ce que tu as déjà proposé pour se rapprocher sans délai de la bonne fonction que tu recherches.

    Pour la regex de ton exemple, c'est simplissime en tenant compte de ceci:
    «il faut considérer qu'un match est appelé dans une fonction qui prend en paramètre la string qui contient les lignes a analyser et l'ER».
    J'étais parti dans la recherche d'une regex qui, non seulement faisait la vérification sur une chaine multiligne mais était destinée à trouver cette chaine en question, commençant par ligne1, dans un fichier.
    Dans la mesure où cette chaine est a priori connue, c'est bien plus simple. Et comme tu dis que pour l'exemple elle comporte 5 lignes, eh bien il suffit d'inscrire littéralement au moins 4 line break '\n' dans le pattern. C'est tout.

    Ce qui donne, en organisant à mon goût ta fonction (tu feras ce que tu veux de mes propositions):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import re
     
    ############### versant général de ton problème
    def maFonction(format,field):
    	print '\n[champ] =',[field]
    	print '[pattern] =',[format]
    	if re.match(format,field):
    		print 'maFonction(pattern,champ) =',True
    	else:
    		print 'maFonction(pattern,champ) =',False
    	return
     
     
    ############## versant application de ton ton problème
    champ1 = """AAAA//0,12345678//dfzdfgfd
    dghsdghssghh
    hsdfgsdfsd
    fghfgffg
    yhjfgjhfghdfghnxf
    """
     
    champ2 = """AAAA//0,12345678//dfzdfgfd
    dghsdghssghh
    hsdfgsdfsd
    fghfgffgkhgkakaksdkajskdjhas.hdalk.sddahsldalsd
    yhjfgjhfghdfghnxf"""
     
    pati = "[A-Z]{1,4}//\d,\d{1,8}//"\
           + 4*"[\w/?;().,'+{} \-]{0,35}\n"\
           +   "[\w/?;().,'+{} \-]{0,35}$"
     
     
    maFonction(pattern,champ1)
    maFonction(pattern,champ2)
    [champ] = ['AAAA//0,12345678//dfzdfgfd\ndghsdghssghh\nhsdfgsdfsd\nfghfgffg\nyhjfgjhfghdfghnxf\n']
    [pattern] = ["[A-Z]{1,4}//\\d,\\d{1,8}//[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n"]
    maFonction(pattern,champ) = True

    [champ] = ['AAAA//0,12345678//dfzdfgfd\ndghsdghssghh\nhsdfgsdfsd\nfghfgffgkhgkakaksdkajskdjhas.hdalk.sddahsldalsd\nyhjfgjhfghdfghnxf']
    [pattern] = ["[A-Z]{1,4}//\\d,\\d{1,8}//[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n[\\w/?;().,'+{} \\-]{0,35}\n"]
    maFonction(pattern,champ) = False
    Le pattern comporte 4 caractères '\n' et un caractère '$' au bout qui permet d'entrer comme field dans la fonction aussi bien une chaine terminant par '\n' telle que champ1 qu'une chaine sans le line break normalement requis, comme champ2.

    Dans l'ensemble définissant les caractères autorisés parmi les 35, j'ai remplacé a-zA-Z0-9 par \w dans un souci de simplification. \w est en effet [a-zA-Z0-9_] c'est à dire qu'il y a l'underscore en plus. C'est à toi de voir ce que tu veux garder.
    Par contre, le caractère '-' ne peut pas être inscrit tel quel au sein des caractères entre [] parce qu'il est un signe qui dans ces conditions a une signification spéciale. Pour échapper son caractère spécial il faut un antislash devant.

    Pour la fonction maFonction(format,field):
    - j'ai interverti l'ordre des arguments que tu avais pris pour correspondre à l'ordre habituel des arguments des fonctions match(), search(),findall() etc
    - dans ton code, ça ne sert à rien de donner la valeur True à la variable valide puisque cette valeur est obligatoirement redéfinie dans le test suivant. Ce doit être dû à l'habitude prise dans la pratique d'autres langages.
    - dans ton code, la fonction retourne la valeur de la variable valide mais une fois dehors tu n'en fais rien. J'ai intégré directement dans la fonction l'affichage du résultat, en éliminant les instructions valide=True et valide=False qui ne sont pas véritablement utiles.

    J'espère avoir cette fois bien compris et que le code simple que je propose correspond à ce que tu attends.
    Si ce n'est pas le cas, j'ai une rgex compliquée en magasin, il suffira de demander

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Oui j'ai finalement réussit a me faire comprendre c'est exactement ça que je recherchait.

    Décidément je n'ai pas que des choses a apprendre en programmation, mais aussi en postant sur les forum... Mais je tire plusieurs enseignement très utiles sur les exemples que tu a laissé.

    Je me suis mis aux ER récemment pour un projet professionnel. j'avais déjà vu en cours très brièvement leurs utilités/utilisations mais je découvre peut a peut la puissance de fonctionnalité qu'elle nous offre.

    Je n'ai pas vraiment le temps en ce moment de me poser sur le sujet et de rentrer plus en profondeur mais des que mon projet est aboutit je m'y collerais.

    Je suis quand même bien curieux de savoir quel type d'ER tu nous avait concocté. Il serai dommage que le fruit de ta réflexion ne soit pas partagé a tous.

    En tout cas merci pour tout et bravo pour le travail réalisé

  13. #13
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    OK, je posterai la regex aprés avoir vérifié ce qu'elle fait et à quoi elle peut servir.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin d'aide pour remplacer avec expression régulière sur plusieurs lignes
    Par MediaVistaIntel dans le forum Général Python
    Réponses: 11
    Dernier message: 01/12/2011, 14h19
  2. [PHP 5.2] expression reguliere sur multiline
    Par Papy214 dans le forum Langage
    Réponses: 6
    Dernier message: 16/04/2009, 10h29
  3. Expression régulière sur même ligne
    Par knebhi dans le forum Langage
    Réponses: 1
    Dernier message: 20/03/2009, 17h49
  4. expression régulière sur plusieurs lignes
    Par [Hugo] dans le forum Langage
    Réponses: 6
    Dernier message: 01/07/2008, 12h48
  5. expressions regulieres sur advice
    Par austin P. dans le forum Spring
    Réponses: 2
    Dernier message: 17/07/2007, 18h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo