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 :

alternative à substr


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 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    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 661
    Billets dans le blog
    1
    Par défaut alternative à substr
    Bonjour,

    Je testais une alternative plus rapide à substr, et je tombe sur ceci que je ne m'explique pas ...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $reg="~(?:^.{43}).{3}~";
    $chaine="artyjnhgtfredcvbhjklopiuytredfbhgtezdsqmloi123";
    preg_match($reg,$chaine,$matches);
    var_dump($matches);
    je m'attendais à avoir 123
    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
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Si tu veux 123, il faut capturer la fin
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonjour,

    pour tout dire, je ne saisi pas ton ?: par contre si tu veux récupérer ton 123, alors il faut l'encadrer par des ()

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $reg="~^.{43}(.{3})~";
    $chaine="artyjnhgtfredcvbhjklopiuytredfbhgtezdsqmloi123";
    preg_match($reg,$chaine,$matches);
    var_dump($matches);

    EDIT: grillé

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    Si j'ai bien compris, il veut seulement "123" dans $matches[0].

    Or, une parenthèse non-capturante (ie (?: ... )) implique également correspondance donc il est normal que la partie de la chaîne de départ qui lui correspond soit mémorisée en 0. D'autant qu'une parenthèse non-capturante peut inclure des capturantes. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if(preg_match('~^(?<jj>\d{2})(?P<sep>[/-])(?<mm>\d{2})(?:\k<sep>(?<aaaa>\d{4}))?$~D', $date, $matches)) {
        if (!isset($matches['aaaa'])) {
            $matches['aaaa'] = date('Y');
        }
    }
    Enfin, l'exemple n'est pas forcément génial et c'est plus "transparent" sur une réécriture d'URL.

    La solution : une assertion positive (arrière ici) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $reg="~(?<=^.{43}).{3}~";
    $chaine="artyjnhgtfredcvbhjklopiuytredfbhgtezdsqmloi123";
    preg_match($reg, $chaine, $matches);
    var_dump($matches);
    array(1) { [0]=> string(3) "123" }

  5. #5
    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 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    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 661
    Billets dans le blog
    1
    Par défaut
    Alors je ne pige pas le principe du "non capturant" ce n'est pas supposé ne pas capturer ?
    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 !

  6. #6
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Ton $matches[0] contiendra quoi qu'il arrive ta chaine complète. Tes occurences débutent à l'offset 1.

    preg_match() retourne le nombre de fois où le masque pattern a été trouvé. Cela peut aller de 0 (pas de solution) à un 1 car preg_match() s'arrête dès qu'elle a trouvé une première solution.

  7. #7
    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 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    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 661
    Billets dans le blog
    1
    Par défaut
    oui ben justement selon ma logique le match[0] devrait pour moi ne contenir QUE 123 vu que le groupe précédent est non capturant ?
    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 !

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    Citation Envoyé par SpaceFrog Voir le message
    Alors je ne pige pas le principe du "non capturant" ce n'est pas supposé ne pas capturer ?
    Si : une non-capturante ne crée pas une nouvelle "variable" de mémorisation ($1, $2, etc). $0 n'est pas véritablement une capture en soi, elle représente la sous-chaîne qui correspond à l'intégralité du motif (parenthèses non-capturantes comprises), faisant partie intégrante du motif et par cohérence, elles sont bien obligées de figurer dans $0.

    Les assertions c'est totalement différent, on fait référence à ce qu'il y a avant ou après (donc hors motif : une partie de la chaîne qui précède ou succède celle qu'on cherche). Il est donc normal, les concernant, de ne pas les y retrouver ni d'être capturantes (à moins de les parenthéser pour qu'elles le deviennent).

  9. #9
    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 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    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 661
    Billets dans le blog
    1
    Par défaut
    autant faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $reg="~(?:^.{43})(.{3})~";
    $chaine="artyjnhgtfredcvbhjklopiuytredfbhgtezdsqmloi123";
    $chaine=preg_replace($reg,'$1',$chaine);
    echo $chaine;
    alors ?
    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 !

  10. #10
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    C'est prendre la chose par un autre bout, mais, oui, éventuellement. Reste à en mesurer les performances

    Par contre, la parenthèse non-capturante, peut être retirée, ne jouant aucun rôle.

  11. #11
    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 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    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 661
    Billets dans le blog
    1
    Par défaut
    ben non justement ce sera moins gourmand puisque ne générant pas de capture ...
    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 !

  12. #12
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    C'est le cas sans aussi et il n'y a rien à grouper là.

  13. #13
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Et finalement alors la différence en terme de temps comparé au substr...?

  14. #14
    Membre Expert Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Par défaut
    Citation Envoyé par Madfrix Voir le message
    Et finalement alors la différence en terme de temps comparé au substr...?
    j'ai fait un essai avec ces 2 fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function substr1($chaine, $debut, $longueur)
    {
        return substr($chaine, $debut, $longueur);
    }
     
    function substr2($chaine, $debut, $longueur)
    {
        $reg = '~(?:^.{' . $debut . '})(.{' . $longueur . '})~';
        preg_match($reg, $chaine, $resultat);
        return $resultat[1];
    }
    et la 1re fonction est plus rapide à chaque fois
    j'ai mis le script de test en pièce jointe, je vous laisse vérifier si c'est représentatif
    Fichiers attachés Fichiers attachés

  15. #15
    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 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    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 661
    Billets dans le blog
    1
    Par défaut
    et si on teste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function substr1($chaine, $debut, $longueur)
    {
        return substr($chaine, $debut, $longueur);
    }
     
    function substr2($chaine, $debut, $longueur)
    {
    return  preg_match( '~(?:^.{' . $debut . '})(.{' . $longueur . '})~', $chaine, $resultat)[1];
     
    }
    pour comparer ce qui est comparable ...
    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 !

  16. #16
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    Malheureusement ce n'est pas valide en PHP, indexer une fonction de façon à se référer au tableau qu'elle retournerait lèvera une erreur de syntaxe. De plus, même si ça l'était, preg_match ne renvoie pas les captures mais un simple entier indiquant le nombre de correspondances (donc 0 ou 1 à moins d'une erreur : FALSE).

  17. #17
    Membre Expert Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Par défaut
    Citation Envoyé par julp Voir le message
    preg_match ne renvoie pas les captures mais un simple entier indiquant le nombre de correspondances (donc 0 ou 1 à moins d'une erreur : FALSE).
    d'où ma dernière remarque "je vous laisse vérifier si c'est représentatif" : SpaceFrog, il faudrait que tu nous expliques quel test tu cherches à faire ? est ce que tu cherches une fonction qui remplace entièrement le comportement de "substr" (index négatif, présence partielle) ?

    par exemple avec '~(?:^.{43})(.{3})~' l'expression régulière ne trouvera rien s'il y a seulement 45 caractères dans la chaine puisqu'elle ne trouvera pas les 3 dernières caractères mais seulement 2

  18. #18
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    Citation Envoyé par SpaceFrog Voir le message
    Bonjour,

    Je testais une alternative plus rapide à substr
    Avec PCRE ? !

    Si c'est juste pour jouer sur les performances brutes, aucune chance.
    Je n'ai aucune démonstration à apporter, mais je n'ai jamais vu le cas.

Discussions similaires

  1. alterner les couleurs dans un tableau avec xsl
    Par Eithelgul dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 03/05/2015, 23h29
  2. Alternative au dbms_output ?
    Par dam1311 dans le forum Oracle
    Réponses: 10
    Dernier message: 24/11/2004, 08h11
  3. [FORMATION] Formations par alternance
    Par chobol dans le forum Etudes
    Réponses: 10
    Dernier message: 20/02/2004, 11h28
  4. [sous-chaine] Avec strpos ou substring ??
    Par terziann dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 17/07/2003, 15h28
  5. Réponses: 2
    Dernier message: 10/07/2002, 11h51

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