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 :

Lien automatique [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut Lien automatique
    Bonjour,

    j'utilise la manip suivante pour modifier mes textes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function affiche_texte_auto_lien ($texte)
                        {
                            $texte =  stripslashes ($texte ) ;  
     
                            $texte = ereg_replace ("arbitre", "<strong><a href=\"../arbitres/arbitre.php\">arbitre</a></strong>" , $texte) ; 
     
                            print (nl2br($texte)) ;
                            return ($texte) ;
     
                        }
    Mon problème est que si je fais pareil pour le mot foot, il génère un lien à l'intérieur même du mot football, ce qui le rend difficilement lisible.
    En revanche, avec foot. et foot, rien ne se passe à cause des signes de ponctuation qui suivent.

    Est-il possible de lui faire reconnaître les mots complets, et non pas les morceaux de mots et de permettre une reconnaissance même si le mot est suivi d'une virgule, d'un point etc... ?
    Par avance, merci de votre aide.

  2. #2
    Membre confirmé Avatar de stunti
    Inscrit en
    Mai 2006
    Messages
    520
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2006
    Messages : 520
    Points : 594
    Points
    594
    Par défaut
    utilise plutot un preg_replace

    voila la regexp (vite fait)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [^0-9,a-z]arbitre[^0-9,a-z]
    If it's not broken, don't fix it.
    BiliBa Built on top of Zend Framework

  3. #3
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    Merci bien pour cette piste.
    Si ce n'est pas trop abuser, ça donne quoi sur un cas concret comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte = ereg_replace ("arbitre", "<strong><a href=\"../arbitres/arbitre.php\">arbitre</a></strong>" , $texte) ;

  4. #4
    Membre confirmé Avatar de stunti
    Inscrit en
    Mai 2006
    Messages
    520
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2006
    Messages : 520
    Points : 594
    Points
    594
    Par défaut
    le mieux :
    PCRE est plus rapide que POSIX
    tu vas sur l'onglet PCRE (preg_*) ou POSIX (ereg*) et tu t'amuses :

    REX V
    If it's not broken, don't fix it.
    BiliBa Built on top of Zend Framework

  5. #5
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    Voilà une réponse qui ouvre encore de nouveaux horizons.
    Merci vraiment beaucoup !

    Rectification : j'ai rien comprendu à cette usine à gaz.
    Si quelqu'un a la solution à mon pb,... !

  6. #6
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    Par hasard, je viens de trouver ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php 
    $ch='Bon alors voilou, la bonne méthode consiste à limiter les 
     mots de façon à éviter de prendre une partie, comme sol dans 
     solide, bravo dans bravoure et bon dans bonne comme au début, 
     même si BRAVO ou BON sont en majuscules ou encore un mix des 
     deux et au pluriel comme BrAVoS.'; 
     
    $mot=array('bravo','bon','sol'); 
     
    $motif='`\b(('.implode('|',$mot).')s?)\b`si'; 
     
    $sortie='<span style="background-color:#ffcc00">$1</span>'; 
    echo preg_replace($motif,$sortie,$ch); 
    ?>
    C'était sur http://www.expreg.com

  7. #7
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte = preg_replace ('/\barbitre\b/', "<strong><a href=\"../arbitres/arbitre.php\">arbitre</a></strong>" , $texte) ;

  8. #8
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    Merci pour ta réponse précise à ma question.

    Une recherche approfonfie sur le web et pas mal d'expérimentation empirique me permettent de proposer ce qui suit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
    $paragraphe ='Dans les années 70, l'équipe de football de Saint-Etienne a fait rêver des milliers de supporters. Sait-on si notre Zizou national n'est pas la concrétisation de ce rêve.';
     
    function affiche_texte_auto_lien ($texte)
        {
            $texte = preg_replace('`\b(('.football.')s?)\b`si','<strong><a href="../football.php">$1</a></strong>',$texte);
            $texte = preg_replace('`\b(('.zizou.')s?)\b`si','<strong><a href="../zinedine-zidane.php">$1</a></strong>',$texte);
            $texte = preg_replace('`\b(('.millier.')s?)\b`si','<strong><a href="../nombres.php">$1</a></strong>',$texte);
     
            print (nl2br($texte)) ;
        }
     
    $paragraphe = affiche_texte_auto_lien ($paragraphe) ;
    ?>
    Ca fait exactement ce que je cherchais et même mieux encore !
    Le hic, ce sont les mots composés : Saint Etienne est refusé.

  9. #9
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Salut

    Il y a de sérieux problèmes à ta regex :/
    Tu concatènes la constante football à la regex mais, puisqu'elle n'existe pas, PHP la convertit en chaîne littérale donc ça marche. Mais ça devrait pas. Normalement, tu devrais avoir un joli Warning à ce sujet : j'imagine que tu as enlevé l'error_reporting dans ton php.ini.

    Solution : remplacer
    par
    Ensuite, tu utilises beaucoup de parenthèses inutiles. Puisque tu sais que tu vas avoir "football", tu n'as pas besoin d'utiliser les parenthèses et $1.

  10. #10
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    La proposition de Mr. N est excellent pour les mots composés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte = preg_replace ('/\bSaint Etienne\b/', "<strong><a href=\"../les-verts.php\">Saint Etienne</a></strong>" , $texte) ;
    Est-ce que quelqu'un comprend le coup du s? et si dans le pattern
    '`\b(('.millier.')s?)\b`si'

    Ca sert à reconnaître la version au pluriel d'un mot proposé initialement au singulier.
    Mais je ne sais pas du tout comment ça fonctionne...

    PS : comment faites-vous pour maîtriser des trucs pareils, les modérateurs et autre participants à ce forums ?

  11. #11
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Le s permet de dire à ton point (dans l'expression) qu'il doit aussi remplacer les sauts de line ("\n" et compagnie). Donc si tu n'as pas de point dans ta regex, tu n'as pas besoin du modificateur s.
    Le i permet d'ignorer la casse (majuscules == minuscules).
    Le point d'interrogation ? permet de matcher, que le caractère soit là ou non. On peut l'appliquer comme l'étoile * (zéro jusqu'à l'infini) et le plus + (au moins un).
    Lis bien la doc PHP sur les regex, tout y est expliqué.

    C'est à force...

  12. #12
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Je dis que le s c'est pour un millier, des milliers

  13. #13
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    De plus en plus tordu !

    J'ai plusieurs mots qui génèrent ce genre de mis en valeur automatique :
    - zizou
    - Platini
    - joueurs
    - etc...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    $texte = "Quelques joueurs français connus internationalement : Michel Platini, Zinédine Zidane, dit Zizou" ; 
     
            $texte = preg_replace('`\b(('.zizou.')s?)\b`si','<strong><a href="../joueur/index.php">$1</a></strong>',$texte);
            $texte = preg_replace('`\b(('.platini.')s?)\b`si','<strong><a href="../joueur/joueur.php">$1</a></strong>',$texte);
            $texte = preg_replace('`\b(('.joueur.')s?)\b`si','<strong><a href="../joueur/index.php">$1</a></strong>',$texte);
     
    print $texte ; 
    ?>
    Miracle : le seul fait que le mot joueur soit à la fois un répertoire et un mot qui se met lui-même en lien par la fonction génère un cafouillage énorme.

    Résultat qui se mord la queue :
    Quelques joueurs français connus internationalement : Michel joueur/joueur.php">Platini, Zinédine Zidane, dit joueur/index.php">Zizou
    Si vous savez comment éviter que la méthode boucle sur elle même...

  14. #14
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Hmmm, comment dire...
    Cela ne t'a pas mis la puce à l'oreille ?
    Un langage de script (comme PHP) n'est pas prévu pour effectuer des tâches trop spécifiques. Si tu répètes une tâche spécifique en changeant peu de choses (c'est le cas pour cette regex), alors peut-être qu'il serait plus intéressant de revoir la structure de ton site.
    En l'occurence, je trouve assez peu judicieux d'avoir une page "zidane.php" : j'aurais essayé de me situer au niveau de la classe plutôt que de l'objet, pour parler en termes de prog orientée objet.

    Exemple : "Zidane" est un joueur de foot. Il n'est probablement pas exclu que tu ajoutes d'autres joueurs par la suite, donc pourquoi ne pas nommer ton script "joueurs.php" et lui donner un paramètre "nom=Zidane" ? Ou bien tu places le tout dans un répertoire joueurs/ et le script d'appelle index.php.
    Finalement, ta regex aura quelque chose comme ceci à remplacer :
    joueurs.php?nom=zidane
    joueurs.php?nom=platini
    joueurs.php
    equipes.php?nom=Saint%20Etienne

  15. #15
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    J'ai enfin trouvé une solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $texte = "Quelques joueurs français connus internationalement : Michel Platini, Zinédine Zidane, dit Zizou." ; 
     
            $texte = preg_replace('`\b(('.joueur.')s?)\b`si','<strong><a href="../joueur/index.php">$1</a></strong>',$texte);
            $texte = preg_replace('`\b(('.zizou.')s?)\b`si','<strong><a href="../joueur.php">$1</a></strong>',$texte);
            $texte = preg_replace('`\b(('.platini.')s?)\b`si','<strong><a href="../joueur/joueur.php">$1</a></strong>',$texte);
     
    print $texte ;
    C'est à dire, commencer par les mots qui sont à la fois mots-clés + noms de répertoires et/ou de fichiers.

    Je ne sais pas pourquoi, mais ça marche.
    NB : ça marche pour les mots isolés, pas les groupes de mots ("Marius Trésor").

  16. #16
    Membre habitué Avatar de php_de_travers
    Inscrit en
    Juin 2004
    Messages
    460
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 460
    Points : 190
    Points
    190
    Par défaut
    Citation Envoyé par Yogui
    Salut

    Il y a de sérieux problèmes à ta regex :/
    Tu concatènes la constante football à la regex mais, puisqu'elle n'existe pas, PHP la convertit en chaîne littérale donc ça marche. Mais ça devrait pas. Normalement, tu devrais avoir un joli Warning à ce sujet : j'imagine que tu as enlevé l'error_reporting dans ton php.ini.

    Solution : remplacer
    par
    Ensuite, tu utilises beaucoup de parenthèses inutiles. Puisque tu sais que tu vas avoir "football", tu n'as pas besoin d'utiliser les parenthèses et $1.
    Merci pour cette correction :

    la nouvelle version de la procédure est :

    $texte = preg_replace('`\b((joueur)s?)\b`si','<strong><a href="../joueur/index.php">$1</a></strong>',$texte);

    Et elle fonctionne très bien.

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

Discussions similaires

  1. [Tableaux] lien automatique en php
    Par e-m.guillaume dans le forum Langage
    Réponses: 9
    Dernier message: 30/01/2006, 23h44
  2. Réponses: 5
    Dernier message: 24/01/2006, 01h16
  3. créer des liens automatiquement mais sans boucle
    Par psychoBob dans le forum Langage
    Réponses: 8
    Dernier message: 15/12/2005, 15h20
  4. [Tableaux] Création de lien automatique
    Par GarGamel55 dans le forum Langage
    Réponses: 3
    Dernier message: 17/09/2005, 17h26
  5. [Tableaux] lien automatique en écrivant un nom
    Par jack1234 dans le forum Langage
    Réponses: 4
    Dernier message: 08/09/2005, 18h27

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