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 :

La fonction preg_replace_callback [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2017
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2017
    Messages : 105
    Points : 53
    Points
    53
    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 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    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
    Invité
    Invité(e)
    Par défaut
    Bonjour,

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

    '#[SELECT|INPUT|RADIO]_(\d+)_(\d+)#'
    Oups....
    Dernière modification par Invité ; 18/09/2019 à 09h25.

  4. #4
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 : 2 858
    Points : 6 556
    Points
    6 556
    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 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    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
    Invité
    Invité(e)
    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)
    Dernière modification par Invité ; 18/09/2019 à 09h27.

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    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 du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2017
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2017
    Messages : 105
    Points : 53
    Points
    53
    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é.

  9. #9
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2017
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2017
    Messages : 105
    Points : 53
    Points
    53
    Par défaut un petit bug
    Bonjour , le code proposé a marché jusqu'à aujourd'hui mais lorsque j'ai mis un nouveau traitement sur le code, un bug est apparu.

    voilà le code proposé en cours:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $text_blocks = preg_replace_callback('~{tpls_(SELECT_|INPUT_|RADIO_|CHECKBOX_|RSELECT_|RINPUT_|RRADIO_|RCHECKBOX_)?(\d+)?_?(.*?)}~', function ($m) {
     ...}, $text_blocks);
    Voilà ce qui a provoqué le bug d'affichage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    {tpls_CHECKBOX_liste {1;2}_liste {1}}
    Le bug c'est que la partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    {tpls_CHECKBOX_liste {1;2}
    qui est prise en compte.

    Quelqu'un a-t-il une suggestion de modification du code ? (merci)

  10. #10
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2017
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2017
    Messages : 105
    Points : 53
    Points
    53
    Par défaut
    Bon j'ai résolu le problème en doublant les accolades par exemple {{tpls_INPUT_101_3}} ou encore {{tpls_CHECKBOX_liste {1;2}_liste {1}}}

+ 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