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 :

La fonction preg_replace_callback [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    novembre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : novembre 2017
    Messages : 47
    Points : 24
    Points
    24
    Par défaut La fonction preg_replace_callback
    Bonjour, je voudrais à partir du code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    <li>AB={tpls_INPUT_100_2_3}</li>
    <li>AH={tpls_INPUT_101_3}</li>
    extraire les parmètres 100 et le reste : 2_3
    et le deuxième cas 101 et le reste : 3

    J'ai écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    preg_replace_callback('~{tpls_(SELECT_|INPUT_|RADIO_)?(\d+)?_?(.*)}~',...
    Le premier paramètre est bien extrait, mais j'obtiens comme deuxième paramètre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    2_3}</li><li>AH={tpls_INPUT_101_3
    Au lieu de 2_3
    C'est "(.*)" qui ne va pas, il faudrait s'arrêter au premier "}" rencontré.
    Merci pour vos suggestions, bonne journée.

  2. #2
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    septembre 2007
    Messages
    8 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : septembre 2007
    Messages : 8 307
    Points : 14 439
    Points
    14 439
    Par défaut
    Bonjour,

    À tester:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $result=  preg_replace_callback('~(.*\{tpls_(SELECT_|INPUT_|RADIO_))(\d+)(_)((\d(_)*)*)\}~',
            function ($matches) {
                return $matches[2].' : '.$matches[4].'<br/>';
            },
            $str);
    Les deux valeurs devraient être capturés avec les indexes 2 et 4 (ou 3 et 5 à tester, il faut compter les blocs ).

    A+.

  3. #3
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    15 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 15 609
    Points : 31 888
    Points
    31 888
    Par défaut
    Bonjour,

    Ça fait beaucoup (trop) de parenthèses...

    '#[SELECT|INPUT|RADIO]_(\d+)_(\d+)#'
    Oups....
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images

  4. #4
    Membre expert Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    mars 2009
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : mars 2009
    Messages : 1 718
    Points : 3 576
    Points
    3 576
    Par défaut
    Pour que ton dernier groupe s'arrête à l'accolade fermante:
    • soit tu remplaces ton quantificateur gourmand * (qui prend le plus possible) par un quantificateur non gourmand *? (qui prend le moins possible, mais qui sera tout de même obligé d'aller jusqu'à l'accolade pour que la pattern réussisse)
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ~{tpls_(SELECT_|INPUT_|RADIO_)?(\d+)?_?(.*?)}~
    • soit tu conserves ton quantificateur gourmand mais tu remplaces le point par une classe de caractères qui ne contient pas l'accolade fermante, comme ça ton quantifier * prendra le plus de caractères possible mais il sera coincé à l'accolade
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ~{tpls_(SELECT_|INPUT_|RADIO_)?(\d+)?_?([^}]*)}~
      ou si tu connais le type de caractères dont il s'agit, autant être le plus précis possible dans ta classe de caractère
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ~{tpls_(SELECT_|INPUT_|RADIO_)?(\d+)?_?([\d_]*)}~


    En regardant ta pattern je vois que pratiquement tout est optionnel, ce qui peut correspondre à des chaînes qui me semblent étranges: {tpls__} ou {tpls_SELECT_} ou {tpls_1} ou {tpls_}. Est-ce que c'est voulu?

    Des exemples de chaînes avec toutes les configurations possibles seraient les bienvenues pour rendre la pattern plus précise. (voire si les astres sont bien alignés, éventuellement se passer de preg_replace_callback pour preg_replace tout court, mais pour ça, il faut plus d'infos).
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    septembre 2007
    Messages
    8 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : septembre 2007
    Messages : 8 307
    Points : 14 439
    Points
    14 439
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Ça fait beaucoup (trop) de parenthèses...
    On peut les virer
    Après, il faut .* au début et à la fin (tu peux épurer si tu connais de l'avance la structure de la page) pour ne pas ramasser les autres caractères.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ~.*={tpls_(SELECT_|INPUT_|RADIO_)(\d+)_([\d_]*)}.*~
    Dans ce cas, les indexes des groupes seront 2 ((\d+)) et 3 (([\d_]*))

    A+.

  6. #6
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    15 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 15 609
    Points : 31 888
    Points
    31 888
    Par défaut
    Oups, j'avais mal lu la contrainte.
    Donc ma 1ère proposition est fausse...

    Cela dit, j'avais dans l'idée de ne pas capturer plus que nécessaire.
    D'où une recherche ce matin sur : "parenthèses non capturantes" -> (?:.......|.......|......) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    $str = '<li>AB={tpls_SELECT_100_2_3}</li>
    <li>AH={tpls_INPUT_101_3}</li>
    <li>AY={tpls_RADIO_102_44_127}</li>
    <li>AZ={tpls_RADIO_103}</li>';
     
    $result =  preg_replace_callback(
    	'~{tpls_(?:SELECT|INPUT|RADIO)_(\d+)_?(\d+_?\d*)?}~',
    	function ($matches) {
    		var_dump( $matches );
    	},
    	$str);
    ?>
    • '~{tpls_(?:SELECT|INPUT|RADIO)_(\d+)_?(\d+_?\d*)?}~' : 2ème paramètre de la forme (rien) ou xx ou xx_yy
    • ou '~{tpls_(?:SELECT|INPUT|RADIO)_(\d+)_?([^}]*)}~' si on récupère dans le 2ème paramètre de la forme (rien) ou "tout avant l"accolade de fin". (comme expliqué par CosmoKnacki)


    Ce qui donne :
    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
    array (size=3)
      0 => string '{tpls_SELECT_100_2_3}' (length=21)
      1 => string '100' (length=3)
      2 => string '2_3' (length=3)
     
    array (size=3)
      0 => string '{tpls_INPUT_101_3}' (length=18)
      1 => string '101' (length=3)
      2 => string '3' (length=1)
     
    array (size=3)
      0 => string '{tpls_RADIO_102_44_127}' (length=23)
      1 => string '102' (length=3)
      2 => string '44_127' (length=6)
     
    array (size=2)
      0 => string '{tpls_RADIO_103}' (length=16)
      1 => string '103' (length=3)
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images

  7. #7
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    septembre 2007
    Messages
    8 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : septembre 2007
    Messages : 8 307
    Points : 14 439
    Points
    14 439
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Oups, j'avais mal lu la contrainte.
    Donc ma 1ère proposition est fausse...
    Après, on ne sait pas s'il traite directement les résultats dans le callback, dans ce cas mon pattern est trop lourd et son pattern devrait fonctionner. Mais quand je vois ça
    Le premier paramètre est bien extrait, mais j'obtiens comme deuxième paramètre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    2_3}</li><li>AH={tpls_INPUT_101_3
    Je pense qu'il travaille sur la valeur retournée par preg_replace_callback.

    A+.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    novembre 2017
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : novembre 2017
    Messages : 47
    Points : 24
    Points
    24
    Par défaut
    bonjour, désolez de vous répondre aussi tardivement mais je prépare un concours en parallèle. Il semble que la proposition de CosmoKnacki semble répondre à mes attentes. Merci à vous tous d'avoir participé.

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Fonction API
    Par margilb dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/07/2002, 11h11
  3. Implémentation des fonctions mathématiques
    Par mat.M dans le forum Mathématiques
    Réponses: 9
    Dernier message: 17/06/2002, 16h19
  4. fonction printf
    Par ydeleage dans le forum C
    Réponses: 7
    Dernier message: 30/05/2002, 11h24
  5. FOnction api specifiant la position de la souris
    Par florent dans le forum C++Builder
    Réponses: 4
    Dernier message: 15/05/2002, 20h07

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