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 :

Preg_replace complexe [RegEx]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut Preg_replace complexe
    Bonjour,

    J'essaie de mettre au point une fonction me permettant de remplacer certain "mot" pour y insérer une infobulle quand on survole le "mot"

    Tout cela n'est pas très clair... alors voici un exemple:
    Mon texte est du type:
    E7 E7/D Bsus

    E7 A D Dmaj7 Bsus b(no 3rd)
    Boy Mercury shootin' through ev'ry degree
    E7 A D Dmaj7 Bsus b(no 3rd)
    Oh-ho girl dancin' down those dirty and dusty trail-ai-ails
    Je veux donc remplacer tous les accords (dans l'ordre E7,E7,D,Bsus,E7,A...) par une infobulle, bref pour cela pas de problème.

    Voici un bout de ma fonction qui fait cela:
    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
    	// Je récupère tous les accords correspondant 
    	$req = mysql_query("SELECT * FROM `accords` INNER JOIN `tab-accord` ON `accords`.id=`tab-accord`.`accord-id` WHERE `tab-accord`.`tab-id` = '$tab_id'"); 
     
    	// Boucle qui va faire les changements pour chaques accords
    	while($accord = mysql_fetch_assoc($req))
    	{
     
    	$tabla = make_tabla($accord[doigt],$accord[accord],$accord[fret]); // Genère le diagramme
     
    	#$pattern = ";([^aA-zZ1-9<()] *)$accord[accord]( */?,?[^\\-|aA-zZ0-9<>#]);";
    	$pattern = ";( +|[^aA-zZ1-9<>] {0}| ?/ ?|[^aA-zZ1-9()] {1})$accord[accord]($| ?/| ?,|[^aA-zZ1-9()#<>|]| +|\([mM]\))([^\w]);s";
     
     
    	$textTab = preg_replace("$pattern", "$1<a class=infob href=\"#\"><span><pre>$tabla</pre></span>$accord[accord]</a>$2$3", $textTab);
     
    	}
    Ceci marche ... mais ma regex rencontre quelques soucis parfois car il y a beaucoup d'exception.
    En effet l'accord à remplacer peut ce trouver:
    - avec 0 caractère devant
    - avec plusieurs espace devant
    - avec un '/' devant
    - avec 0 ou plusieurs espace après
    - sans texte avant ou apres (pour ne pas remplacer les paroles)
    - ...

    Bref je suis un peu perdu... voyez vous un moyen de faire un preg_replace plus propre ? Ou une meilleur solution ?

    Merci d'avance pour votre aide.

  2. #2
    Membre chevronné Avatar de goodpz
    Profil pro
    Inscrit en
    Février 2007
    Messages
    475
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 475
    Par défaut
    - avec 0 caractère devant
    - avec plusieurs espace devant
    - avec un '/' devant
    - avec 0 ou plusieurs espace après
    - sans texte avant ou apres (pour ne pas remplacer les paroles)
    Ca correspond à peu près au metachar '\b' (word boundary)

    Je n'ai pas vraiment compris ton pattern (dont je me demande d'ailleurs comment ce fait-il qu'il 'marche' ; )
    Que fait tu des suffixes 'sus4', '(no 3rd)'.. Tu les mets dans le <a> ou à coté ?

    EDIT: Pour 'Dmaj7' par exemple, dans $accord['accord'], tu aurais 'D' ou directement 'Dmaj7' ?

    Aussi, pour les keys des arrays, utilises $accord['doigt'] plutôt que $accord[doigt], sauf si doigt est une constante (ce dont je doute). Sinon ça peut devenir très problématique...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut
    C'est noté pour le ' , merci
    Sinon oui pour Dmaj7 j'ai bien "Dmaj7" en entier dans $accord['accord'], ainsi que Bsus ... (sauf (no 3rd))
    Les accord peuvent être de la forme:
    X: lettre
    Y: chiffre

    X
    XY
    Ym
    YmajY
    X#m
    X#
    Xsus...

    Bref il y a plein de forme

    Je regarde le metachar '\b'

  4. #4
    Membre chevronné Avatar de goodpz
    Profil pro
    Inscrit en
    Février 2007
    Messages
    475
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 475
    Par défaut
    Donc en fait dans $accord tu as déjà toutes les formes:

    X
    XY
    Ym
    YmajY
    X#m
    X#
    Xsus...

    Sauf (no 3rd) ?

    J'ai l'impression que ceci te conviendrait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $pattern = '~\b'.$accord['accord'].'(?(?=\()([^)]+)|.*?\b)~';
    Et le replace se ferait avec (simplement):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '<a class="infob" href="#"><span><pre>'.$tabla.'</pre></span>'.$accord['accord'].'</a>\1'
    Mais je m'avance peut être un peu trop car j'ai à moitié rien compris à ton pattern initial

    Edit: et oui, je connais la forme des accords, guitariste aussi ; )

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut
    C'est vrai que mon pattern était pas mal

    Sinon je pense qu'il y a un problème avec le tiens:
    Il a l'air de remplacer également les <A des balises de liens ... donc en gros ca fais une boucle infini

  6. #6
    Membre chevronné Avatar de goodpz
    Profil pro
    Inscrit en
    Février 2007
    Messages
    475
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 475
    Par défaut
    Tu as raisons, vu que tu boucles, ça merde avec LA ; )

    Et si tu mets ça en début de pattern:

    '\b(?<!<|>)'

    Et sinon, si on prend le cas de, par exemple, Dmaj7 et Dmaj7b5. Tu les remplaces dans un certain ordre ?

    Edit: modif

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

Discussions similaires

  1. [RegEx] preg_replace assez complexe
    Par Info-Rital dans le forum Langage
    Réponses: 2
    Dernier message: 25/11/2005, 13h28
  2. Encore une requête complexe sur plusieurs tables
    Par DenPro dans le forum Langage SQL
    Réponses: 5
    Dernier message: 09/12/2003, 19h05
  3. Requête complexe sur plusieurs table
    Par DenPro dans le forum Langage SQL
    Réponses: 13
    Dernier message: 25/11/2003, 17h50
  4. Réponses: 5
    Dernier message: 04/08/2003, 21h50
  5. Réponses: 7
    Dernier message: 07/04/2003, 09h35

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