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

Langage PHP Discussion :

Retrouver les sous-groupes nommés dans les résultats


Sujet :

Langage PHP

  1. #1
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut Retrouver les sous-groupes nommés dans les résultats
    J'avoue essayer de faire un truc assez barabare.

    le contexte:

    je dispose d'un fichier texte multiligne
    une ligne dépend d'une suite d'ensembles de caractères
    chaque suite de x caractères est un champs
    pour le debut de ligne aucun souci
    ici champs1 2 et 3
    je fais un match sur une reg qui récupère les groupes nommés en fonction du nombre de caractères par groupe avec preg_match_all

    Là ou ça se complique c'est que la fin de la ligne, (ce qui est dans log est un motif répété des champs 4 5 6 7 8

    je retrouve bien la chaine complète dans $matches['log'],
    mais je ne recupère à priori que la dernière occurence des sous groupes nommés ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #^(?P<champs1>.{1})(?P<champs2>.{11})(?P<champs3>.{3})(?P<log>((?P<champs4>.{2})(?P<champs5>.{8})(?P<champs6>.{2})(?P<champs7>.{50})(?P<champs8>.{80}))+)$#u
    comment recupérer les sous groupes ?
    suis-je obligé de refaire un preg_match_all sur le $matches['log']
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  2. #2
    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
    suis-je obligé de refaire un preg_match_all sur le $matches['log']
    Je le pense.



    C’est le même problème que celui posé dans ce post:

    http://www.developpez.net/forums/d95...es-imbriquees/





    En Python, le problème se règle très bien avec findall() qui est la même chose que preg_match_all()

    Ça donne en Python: (j’ai remplacé les sections de 50 et 80 caractères par des sections de 5 et 8 caractères) :

    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
    ch = ('AiiiiiiiiiiihhhAB,,$%%$,,HU**-**QWTRSNMPBA^^::::^^UH?????SPQRGOOGLE-*-*-*-*UU::;::GARAGAGA\n'
          'BjjjjjjjjjjjkkkDE%$#^^#$%PW*-**-xdhyrteoEE::^::^::WW!!?!!MICROSOFTS,,,,,,,,PP"";""gulugulu\n'
          'CkkkkkkkkkkkrrrUU12345678VT---*-atlantiqUE!=!=!=!=TT!?!?!montagneEE::"":"::VVudtqckokololo\n')
     
    import re
     
    RE = '^(?P<champs1>.{1})(?P<champs2>.{11})(?P<champs3>.{3})(?P<log>(?:.{25})+)$'
    RE45678 = ('(?P<champs4>.{2})(?P<champs5>.{8})(?P<champs6>.{2})'
               '(?P<champs7>.{5})(?P<champs8>.{8})')
     
    pat = re.compile(RE,re.M)
    pat45678 = re.compile(RE45678)
     
     
    for m in pat.finditer(ch):
        res =  list(m.group(1,2,3)) + pat45678.findall(m.group('log'))
        print '\n'.join(repr(x) for x in res)
        print
    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
    'A'
    'iiiiiiiiiii'
    'hhh'
    ('AB', ',,$%%$,,', 'HU', '**-**', 'QWTRSNMP')
    ('BA', '^^::::^^', 'UH', '?????', 'SPQRGOOG')
    ('LE', '-*-*-*-*', 'UU', '::;::', 'GARAGAGA')
     
    'B'
    'jjjjjjjjjjj'
    'kkk'
    ('DE', '%$#^^#$%', 'PW', '*-**-', 'xdhyrteo')
    ('EE', '::^::^::', 'WW', '!!?!!', 'MICROSOF')
    ('TS', ',,,,,,,,', 'PP', '"";""', 'gulugulu')
     
    'C'
    'kkkkkkkkkkk'
    'rrr'
    ('UU', '12345678', 'VT', '---*-', 'atlantiq')
    ('UE', '!=!=!=!=', 'TT', '!?!?!', 'montagne')
    ('EE', '::"":"::', 'VV', 'udtqc', 'kokololo')

    La ligne print '\n'.join(repr(x) for x in res) est simplement là pour la présentation des résultats sur plusieurs lignes.






    En PHP, ça doit donner quelque chose du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    preg_match_all($pattern,$ch,$matches,PREG_PATTERN_ORDER);
    foreach $m in $matches:
        echo $matches[1].'  '.$matches[2].'  '.$matches[3];
        preg_match_all($pattern45678,$matches[4],$sousmatches,PREG_PATTERN_ORDER);
        foreach $mm in $sousmatches:
            echo '( '.$sousmatches[1].'  '.$sousmatches[2].'  '.$sousmatches[3].'  '.$sousmatches[4].' )';
    Sans garantie d’exactitude complète car je n’ai pas testé.








    De mon avis, le nommage des groupes est inutile:

    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
    ch = ('AiiiiiiiiiiihhhAB,,$%%$,,HU**-**QWTRSNMPBA^^::::^^UH?????SPQRGOOGLE-*-*-*-*UU::;::GARAGAGA\n'
          'BjjjjjjjjjjjkkkDE%$#^^#$%PW*-**-xdhyrteoEE::^::^::WW!!?!!MICROSOFTS,,,,,,,,PP"";""gulugulu\n'
          'CkkkkkkkkkkkrrrUU12345678VT---*-atlantiqUE!=!=!=!=TT!?!?!montagneEE::"":"::VVudtqckokololo\n')
     
     
    import re
     
    RE = '^(.{1})(.{11})(.{3})((?:.{25})+)$'
    RE45678 = ('(.{2})(.{8})(.{2})(.{5})(.{8})')
     
    pat = re.compile(RE,re.M)
    pat45678 = re.compile(RE45678)
     
     
    for m in pat.finditer(ch):
        res =  list(m.group(1,2,3)) + pat45678.findall(m.group(4))
        print '\n'.join(repr(x) for x in res)
        print




    La seule petite “astuce“ dans ces codes est de ne pas écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    RE = ('^(?P<champs1>.{1})(?P<champs2>.{11})(?P<champs3>.{3})'
    '(?P<log>'
    '(?P<champs4>.{2})(?P<champs5>.{8})(?P<champs6>.{2})'
    '(?P<champs7>.{5})(?P<champs8>.{8}))+)$'


    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '^(?P<champs1>.{1})(?P<champs2>.{11})(?P<champs3>.{3})(?P<log>(?:.{25})+)$'
    pour alléger le travail du moteur de recherche en première détection.

  3. #3
    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
    PS
    Après quelques réflexions suite a mon précédent post dans lequel j’ai écrit:

    En Python, le problème se règle très bien avec findall() qui est la même chose que preg_match_all()
    je ne crois finalement pas que findall() et preg_match_all() aient la même facilité d’utilisation.

    Car findall() produit une liste tandis que preg_match_all() est une fonction qui ne renvoie pas la même liste mais un nombre 0 ou 1.
    Donc pour disposer de la même liste que celle renvoyée par findall() , il faut en PHP au moins deux lignes, non ?


    En Python,
    m.group(1,2,3) produit un tuple, c’est pourquoi j’ai écrit tuple(m.group(1,2,3)) pour pouvoir additionner tuple(m.group(1,2,3)) et pat45678.findall(m.group('log'))
    Mais à ceci près, l’obtention du résultat est simple et en une ligne.



    Je ne suis pas sûr qu’il en soit de même en PHP car les variables $matches et $sousmatches sont des tableaux, c’est à dire des machins un peu multiformes que je ne sais pas bien manipuler.



    Donc j’aimerais savoir comment faire pour obtenir en PHP un équivalent de m.group(1,2,3) à partir de $matches et un équivalent de pat45678.findall(m.group('log')) à partir de $sousmatches
    et s’il est possible d’associer ces équivalents, tout ça en une seule ligne comme en Python.

    J’en doute un peu.

    La réponse m’intéresse.

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/10/2013, 12h09
  2. [AC-2003] Compter les sous-groupes dans un groupe
    Par jeanpierre78 dans le forum IHM
    Réponses: 4
    Dernier message: 14/12/2010, 12h11
  3. se ballader dans les sous repertoires
    Par Krispy dans le forum Langage
    Réponses: 1
    Dernier message: 30/03/2006, 15h46
  4. [MS-DOS] Supprimer tout les sous répertoires contenu dans un
    Par Furius dans le forum Scripts/Batch
    Réponses: 7
    Dernier message: 30/11/2005, 12h24
  5. [IB 6, FireBird 1.5] SKIP dans les sous-requêtes
    Par Magnus dans le forum Langage SQL
    Réponses: 8
    Dernier message: 15/09/2005, 14h14

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