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 :

comment multiplier dans une expression régulière avec preg_match


Sujet :

Langage PHP

  1. #1
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut comment multiplier dans une expression régulière avec preg_match
    Bonjour,

    Savez-vous comment multiplier 5 fois ceci (.*\-) ce qui revient à faire (.*)\-(.*)\-(.*)\-(.*)\- mais c'est histoire de simplifier...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/(.*\-){5}/', $string, $match);
    Merci d'avance pour votre réponse,

  2. #2
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 438
    Points : 4 936
    Points
    4 936
    Par défaut
    Bonjour,

    je pense que tu n'es pas obligé d'utiliser une expression régulière pour ça, car str_replace permet de remplacer directement une chaîne de caractères, et str_repeat permet de répéter une chaîne de caractères "n" fois, et donc si on combine les deux :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
    $string='abcdef 123 abcdef (.*)/- abcdef 123 abcdef (.*)/-';
    $sujet='(.*)/-';
    echo str_replace($sujet,str_repeat($sujet,5),$string);
     
    //résultat : abcdef 123 abcdef (.*)/-(.*)/-(.*)/-(.*)/-(.*)/- abcdef 123 abcdef (.*)/-(.*)/-(.*)/-(.*)/-(.*)/-

    Sinon, avec une expression régulière, tu peux par exemple utiliser preg_replace :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?php
    $string='abcdef 123 abcdef (.*)/- abcdef 123 abcdef (.*)/-';
    echo preg_replace('/\(\.\*\)\/-+/i',str_repeat('(.*)/-',5),$string);
     
    //résultat : abcdef 123 abcdef (.*)/-(.*)/-(.*)/-(.*)/-(.*)/- abcdef 123 abcdef (.*)/-(.*)/-(.*)/-(.*)/-(.*)/-

  3. #3
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    en fait ce qui m’intéresse, c'est de récupérer dans une chaine, n'importe quels caractère situé avant et avec le tiret du 6, 5 fois, exemple : csd6c4sd6-csd6c4sd564-1csd-5f0-a6546a

  4. #4
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 438
    Points : 4 936
    Points
    4 936
    Par défaut
    Bonjour,

    Je n'ai pas vraiment compris ce que tu cherches à faire exactement.

    Peux-tu nous montrer un exemple de code simple de ce que tu as et de ce que tu veux obtenir comme résultat ?

  5. #5
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    J'avais bien compris que tu n'avais pas compris ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $machaine = "6c4sd6-c4sd564-1csd-5f0-a6546a-1csd-5f0-a6546a"
    les blocs peuvent avoir 2 à 10 caratères alphanumériques séparés par des tirets du 6...
    Ce qui m'intérresse c'est de récupérer les 5 premiers blocs. Donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/^(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-/i', $machaine, $match);
    mais au lieu de répéter 5 fois ce format (.*)\-, je voulais juste savoir si on pouvait faire une multiplication de celui-ci, à la différence de la quantification => {,} qui ne semble pas savoir le faire.

    c'était juste par curiosité, sinon ça fonctionne très bien comme ça...

  6. #6
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Citation Envoyé par dominos Voir le message
    en fait ce qui m’intéresse, c'est de récupérer dans une chaine, n'importe quels caractère situé avant et avec le tiret du 6, 5 fois, exemple : csd6c4sd6-csd6c4sd564-1csd-5f0-a6546a
    Pour rechercher cette chaine, la regex serait la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match("#(-?[a-z0-9]+){5}#", $string, $match);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match("#([a-z0-9]+-?){5}#", $string, $match);
    "-?" permet de dire "avec ou sans tiret après une suite de chiffres ou de lettres ([a-z0-9]+))"

  7. #7
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 438
    Points : 4 936
    Points
    4 936
    Par défaut
    Bonjour,

    Dans ce cas, la solution de two3d est bonne, comme on peut aussi remplacer le [a-zA-Z0-9] par \w :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <?php
    preg_match("#(\w+-?){5}#", $string, $match);

  8. #8
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Non, \w ne remplace pas la classe [A-Za-z0-9]car il accepte aussi "_" et les lettres accentués, à faire attention.

    \w = [A-Za-z0-9_] plus les accentués
    HS: comment t'arrive à mettre en valeur des portions de texte ?

    Nom : Screenshot 2022-05-22 at 00-21-45 comment multiplier dans une expression régulière avec preg_mat.png
Affichages : 116
Taille : 2,9 Ko

  9. #9
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Citation Envoyé par dominos Voir le message
    mais au lieu de répéter 5 fois ce format (.*)\-, je voulais juste savoir si on pouvait faire une multiplication de celui-ci, à la différence de la quantification => {,} qui ne semble pas savoir le faire.

    c'était juste par curiosité, sinon ça fonctionne très bien comme ça...
    Tu as raison, il récupère que la dernière portion des 5...

    Tu peux par contre utiliser explode("-", $macth) sur le résultat et tu a le tableau des 5 portions.

    Les anti-slash sont inutiles pour le tiret s'il n'est pas utilisé dans une classe : \- peut être -, pour :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '/^(.*)\-(.*)\-(.*)\-(.*)\-(.*)
    Attention :

    - Avec le caractère . tu accepte tous les caractères
    - Tu accepte 0 ou plusieurs caractère avec *, donc ceci serait correct :
    é--\"-'(-è_ç
    - Tu demande un début ^ mais pas une fin $, donc ceci serait correct :
    é--\"-'(-è_ç et ce texte d'exemple serait accepté aussi...

  10. #10
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    Merci pour cette réflexion. En effet (.*) récupère tous les caractères éventuels, il est plus correcte d'utiliser \w mais cela ne semble pas fonctionner.
    Les exemples cités récupèrent seulement le cinquième bloc et pas les 5 premiers, et quantifier {1,5} ne retourne pas non plus les 5 premiers blocs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    preg_match('/^([a-z0-9]+-){0,5}/i', $machaine, $match);
     echo $match[1];
    De plus le dernier bloc ne doit pas se termine par "'-", donc il semble difficile de faire mieux que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/^(.*)-(.*)-(.*)-(.*)/i', $machaine, $match);

    Ps: j'ai supprimé l'antislash.

    Encore merci.

  11. #11
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Citation Envoyé par dominos Voir le message
    De plus le dernier bloc ne doit pas se termine par "'-", donc il semble difficile de faire mieux que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/^(.*)-(.*)-(.*)-(.*)/i', $machaine, $match);
    Si $machaine est comme ceci :

    des lettres et/ou chiffres-des lettres et/ou chiffres-des lettres et/ou chiffres-des lettres et/ou chiffres-des lettres et/ou chiffres
    alors tu doit faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/^([a-z0-9]+)-([a-z0-9]+)-([a-z0-9]+)-([a-z0-9]+)-([a-z0-9]+)$/i', $machaine, $match);

    et tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/^([a-z0-9]+-){4}([a-z0-9]+)$/i', $machaine, $match);
    Car ton code accepte tout et n"importe quoi, comme je l'ai dit plus haut, ceci est accepté :

    é--\"-'(-è_ç et ce texte d'exemple serait accepté aussi...
    Tant qu'il y a 4 - tiret, la chaine est acceptée, et c'est pas ce que tu souhaite, à mon avis...

    {0,5} veut dire 0 ou 5 fois la demande qui la précède, donc :

    rien

    ou

    abcd123-

    ou

    abcd123-abcd123-

    ou

    abcd123-abcd123-abcd123-

    ou

    abcd123-abcd123-abcd123-abcd123-

    ou

    abcd123-abcd123-abcd123-abcd123-abcd123-
    Ensuite pour ty retrouver dans le tableau retournée, tu peux nommer les sous-masques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $machaine = "abc1-abc2-abc3-abc4-abc5";
     
    preg_match('/^(?<partie1>[a-z0-9]+)-(?<partie2>[a-z0-9]+)-(?<partie3>[a-z0-9]+)-(?<partie4>[a-z0-9]+)-(?<partie5>[a-z0-9]+)$/i', $machaine, $match);
     
     
    var_dump($match['partie1']); //abc1

  12. #12
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    merci pour ces explications complémentaires, j'ai testé la solution que tu proposes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     $machaine = "561cd55scds-Ed65-h8979797h987h-eeee7-000aaaa444-44f-8a12-fffa12-a3sfdss42-3s12-000001a";
     preg_match('/^([a-z0-9]+-){5}([a-z0-9]+)$/i',$machaine, $match);
     echo $match[1];
    mais ça ne fonctionne pas...

  13. #13
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    C’est évident, ta chaine n'est plus dans le format que tu nous l'avez donnée, mais est maintenant avec 11 blocs au lieu de 5, ta regex serait alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match('/^([a-z0-9]+-){10}([a-z0-9]+)$/i',$machaine, $match);

  14. #14
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    ce que je souhaite, c'est juste de récupérer les « 5 premiers blocs » d'une suite pas le bloc 10...

  15. #15
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 438
    Points : 4 936
    Points
    4 936
    Par défaut
    Bonjour,

    $match[0] au lieu de $match[1] :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    preg_match('/^([a-z0-9]+-?){5}/i',$machaine, $match);
    echo $match[0];//affiche :561cd55scds-Ed65-h8979797h987h-eeee7-000aaaa444-

  16. #16
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /^([a-z0-9]+-){4}([a-z0-9]+)/i

  17. #17
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Oui, c'est exact, pour expliquer un peu :

    ^ <- commencera dès le début de la chaine
    ([a-z0-9]+-){4} <- 4 x "[a-z0-9]+-"
    ([a-z0-9]+) <- plus une dernière suite sans tiret
    i <- insensible à la casse, a ou A dans les blocs sera accepté

    Comme je disais, avec explode tu peux en faire un tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $machaine = "abc1-abc2-abc3-abc4-abc5-abc6-abc7-abc8-abc9-abc10-abc11";
     
    preg_match('/^(-?[a-z0-9]+){5}/i', $machaine, $match); //j'ai mis le tiret au début pour pas l'avoir à la fin et avoir une valeur nulle dans le tableau final
     
    var_dump(explode("-", $match[0]));
    /*
    array (size=5)
      0 => string 'abc1' (length=4)
      1 => string 'abc2' (length=4)
      2 => string 'abc3' (length=4)
      3 => string 'abc4' (length=4)
      4 => string 'abc5' (length=4)
    */

  18. #18
    Membre actif
    Inscrit en
    Février 2009
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 626
    Points : 237
    Points
    237
    Par défaut
    merci pas mal l'astuce du -? avant, pour ne s'appliquer sur le dernier bloc.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 24/05/2010, 13h15
  2. Réponses: 5
    Dernier message: 31/08/2006, 13h34
  3. Parenthèses dans une expression régulière
    Par papyreno dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 10/05/2006, 16h28
  4. [EXP] Evaluation dans une expression régulière
    Par SergentHeinz dans le forum Langage
    Réponses: 7
    Dernier message: 10/11/2005, 18h17
  5. Réponses: 6
    Dernier message: 17/08/2005, 12h38

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