Expression régulière : Remplacement d'une chaine aléatoire

Nouveau WRInaute
Bonjour à tous !

Alors voici mon problème. J'ai un système de newsletter perso dans lequel j'upload d'un côté les images, de l'autre mon code HTML afin que celui-ci puisse être envoyé par mail. Mes photos sont chargées sur mon serveur et le code HTML perd ainsi le chemin relatif d'accès aux images (chemin local différent du chemin sur le serveur).

Ce dont j'aurai envie c'est de pouvoir remplacer un bout de code tel que celui-ci :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="file:///C|/Documents and Settings/Sebastien/Bureau/Dossier 1/nom_aleatoire_1.jpg" width="300" height="200" />
<img src="file:///C|/Documents and Settings/Sebastien/Bureau/Dossier 2/nom_aleatoire_2.gif" width="300" height="200" />
...</p></div>

Par un code directement fonctionnel sur le serveur du type :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="./images_newsletter_1/image_1.jpg" width="300" height="200" />
<img src="./images_newsletter_1/image_2.jpg" width="300" height="200" />
...</p></div>


J'ai fait quelques recherches et il se trouve que la fonction PHP preg_match () soit la réponse à mes interrogations. Seulement voila, j'ai beau avoir quelques connaissances dans les expressions régulières, j'avoue que les patterns utilisés dans les exemples que j'ai pu trouver me sont incompréhensibles.

Voici ce dans quoi je m'étais lancé mais sans succès :
Code:
$codehtml = preg_replace('!src=\"(.+)\"!', 'src="../../html/images_newsletter_'.$dossier_en_cours.'/'.$nom_image.'"', $codehtml);

Merci d'avance aux pros des expressions régulières :p
 
Nouveau WRInaute
Le HTML change entre chaque newsletter, il n'est pas fixe : taille des images, emplacement sur la page, liens sur certaines images, alignement sur la page... Je prends mon logiciel HTML favori en mode WYSIWYG et le tour est joué.

Non la seule chose qui me manque c'est cette expression régulière...
 
WRInaute passionné
Je suis tétu, mais je ne vois pas en quoi c'est différent d'utiliser des images locale plutôt que les images depuis ton serveur dans ton logiciel WYSIWYG. Ca résoudrait ton problème d'expression réguliére vu que tu en aurais plus besoin.

Sinon en mettant un chemin relatif directement en local idem, mais ton html est lu depuis où?
 
Nouveau WRInaute
Tu es tétu oui mais ce n'est pas forcément un défaut ^^

Tu te doutes bien que si j'utilise cette méthode c'est parce que je n'en ai pas trouvé d'autre. Le problème c'est que le serveur m'appartient mais la newsletter c'est pour un ami. Il n'y connait rien en HTML donc je ne peux pas lui demander de sortir du code propre, avec des chemins relatifs dans une arborescence similaire à celle sur le serveur, il va me dire parle français stp. En plus j'ai seul accès au FTP, il n'y connait rien il aurait vite fait de tout me planter :lol:

Du coup je lui ai dit de simplement utiliser son logiciel en mode WYSIWYG et moi derrière je m'occupe de faire les traitements pour que tout marche bien comme il faut. Voila ^^

En effet si j'étais seul à gérer ce serait plus simple même si, maintenant que je suis confronté à ce problème, je trouve qu'il s'agit d'un défi vraiment intéressant à relever. De plus, une fois ce cas maitrisé, plein d'applications peuvent en découler. Je pense notamment à remplacer une expression prédéfinie par un lien vers une autre page du site. Mais ça c'est une autre histoire chaque chose en son temps :)
 
WRInaute accro
J'ai une appli sur le même modèle, et perso je passe par un système de TAGS perso qui me permet de générer les bonnes url en fonction des clients, serveurs d'installation du script, etc.

Au moment où je parse le flux, je n'ai qu'à faire des rechercher-remplacer, beaucoup plus simple qu'une expreg tordue...
 
Nouveau WRInaute
Le rechercher/remplacer marche lorsque tu connais d'avance le mot à remplacer.
Chercher 'chat' dans la phrase 'j'aime les chats' et le remplacer par 'chien'.

Le soucis ici c'est qu'on ne connait pas par avance l'expression à remplacer...
 
WRInaute accro
Et pourquoi ne pas avoir l'éditeur WYSIWYG (TinyMCE) directement dans l'application de newsletter plutôt que d'utiliser un programme à part?
 
Nouveau WRInaute
Le fait que l'éditeur WYSIWYG soit implanté dans l'application ne changera en rien le chemin relatif vers les fichiers qui eux sont sur l'ordinateur avant d'être copiés sur le serveur.

Je veux juste une belle expression régulière toute tordue (dixit "UsagiYojimbo"), pas besoin de confronter les points de vue sur la façon de faire les choses ^^
 
WRInaute accro
Justement, passer par un WYSIWYG comme Fckeditor te permettrait de directement uploader tes visuels sur le serveur, et donc d'avoir directement les bonnes url.
 
WRInaute passionné
Et comment tu fais pour savoir que l'image :
Code:
C|/Documents and Settings/Sebastien/Bureau/Dossier 1/nom_aleatoire_1.jpg
Corresponde à :
Code:
/images_newsletter_1/image_1.jpg
et non à :
Code:
/images_newsletter_1/image_2.jpg

???

Il faut forcément un point commun entre les deux nomages, sinon le résultat sera complètement mélangé.

Tu n'as qu'à faire uploader une archive ZIP, au moins tu auras tout en main pour faire les renommages appropriés.
 
Nouveau WRInaute
Le traitement s'effectue à la volé dans le script PHP je récupère un champ image_1 de mon formulaire et quand je le récupère et que j'upload la photo je la nomme selon une règle de nomage prédéfinie. De ce côté là aucun soucis vraiment tout marche nickel à part cette expression régulière.

Et pour le WYSIWYG, comme vous semblez tous les deux convaincu je pense que ce fonctionnement doit être très intéressant et à creuser. Cependant le code html généré par les logiciels de WYSIWYG est impropre à l'envoi par newsletter car non conforme aux réglementations W3C et le résultat sur les logiciels de messagerie sera aléatoire. De plus, mon système est à 90% opérationnel et la seule réponse que vous pouvez m'apporter c'est refait tout en WYSIWYG. J'ai du mal à y croire où sont passés les professionnels des expressions régulières :lol:
 
WRInaute passionné
Le traitement s'effectue à la volé dans le script PHP je récupère un champ image_1 de mon formulaire et quand je le récupère et que j'upload la photo je la nomme selon une règle de nomage prédéfinie. De ce côté là aucun soucis vraiment tout marche nickel à part cette expression régulière.

Et au niveau de ton expression régulière, comment tu fais la correspondance ?
Pour faire le remplacement dans le code HTML il faut la correspondance "nom original" => "nouveau nom".
 
Nouveau WRInaute
Re: Expression régulière : Remplacement d'une chaine aléatoi

lesissoux a dit:
Voici ce dans quoi je m'étais lancé mais sans succès :
Code:
$codehtml = preg_replace('!src="(.+)"!', 'src="../../html/images_newsletter_'.$dossier_en_cours.'/'.$nom_image.'"', $codehtml);

Ici tu vois j'ai mes variables PHP $dossier_en_cours et $nom_image qui permettent de faire la correspondance avec le numéro de la newsletter et le nom de l'image une fois renommée.
 
WRInaute passionné
Dans quelle variable se trouve la liste des noms d'image originaux ? Et les nouveaux noms ?

Une fois que tu auras ces éléments, l'expression régulière est plutôt simple...
 
Nouveau WRInaute
Les noms je les récupère sans soucis c'est l'arborescence vers ces fichiers qui elle est variable et que je ne maitrise pas, d'où le problème pour l'expression régulière.
 
WRInaute passionné
... l'arborescence on s'en fout. Je t'aurais faite l'expression régulière si tu y mettais un peu du tiens, mais visiblement y a rien à faire.

Je laisse tomber là, bon courage.
 
Nouveau WRInaute
Bon alors on va faire plus simple puisque à part me dire de refaire tout à votre sauce vous n'êtes pas capable de m'aider plus que ça.

Je n'ai pas d'upload de fichier à faire rien du tout oubliez tout ça. J'ai un fichier HTML du type :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="chemin_aleatoire_impossible_a_connaitre/image_1.jpg" width="300" height="200" />
<img src="chemin_aleatoire_impossible_a_connaitre/image_2.jpg" width="300" height="200" />
...</p></div>

Je le parse et via des expressions régulières je veux obtenir ceci :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="./images/chemin_que_jai_decide/image_1.jpg" width="300" height="200" />
<img src="./images/chemin_que_jai_decide/image_2.jpg" width="300" height="200" />
...</p></div>

Bref, il faut remplacer ce qui est dans src="(.*)" par src="./images/chemin_que_jai_decide/image_x.jpg"
 
WRInaute passionné
Mais c'est qu'il est adorable le chérubin :D Je crois pourtant avoir proposé mon aide... à la condition de savoir dans quelles variables tu as stocké cette fichue liste de correspondance.

C'est pourtant pas compliqué : tu veux remplacer A par B ainsi que C par D, mais on a aucune de ces 4 variables (je parle bien des noms de fichiers uniquement, et pas des dossiers hein).
L'expression régulière à partir de ça est extrèmement simple, mais tu t'obstines à ne pas vouloir répondre à une simple question.

Dans ton dernier exemple tu nommes "image_1.jpg" l'image "avant" et "après" : c'est un hasard ou bien tu as changé de technique en cours de route ?
 
Nouveau WRInaute
C'était pour faire simple, je vous ai dit d'oublier les noms des images puisque là n'est pas mon problème mais puisque tu insistes.

Je récupère le nom temporaire de l'image de l'utilisateur lors de la validation du formulaire en récupérant ce champ :
Code:
$fichier_temporaire = $_FILES['image_1']['tmp_name']
le image_1 étant bien sûr un exemple, sauf que je connais le nom du champ lorsque j'en fait l'appel.

Ensuite lors de l'upload je donne le nom que je souhaite à mon image :
Code:
if(move_uploaded_file($fichier_temporaire, $repertoire_que_je_choisi."/".$nom_que_jai_choisi))

Comme j'ai choisi le nom du répertoire et le nom du fichier ce n'est pas un problème je sait par quoi je dois remplacer mon expression. Il me reste à décrypter l'expression initiale.

J'ai par exemple :
Code:
<img src="arborescence_utilisateur_inconnu/nom_image_connu.jpg" ... />

Et je veux obtenir ceci :
Code:
<img src="repertoire_que_je_choisi/nom_que_jai_choisi.jpg" ... />

Je veux simplement remplacer arborescence_utilisateur_inconnu une variable qu'il m'est impossible de connaitre par repertoire_que_je_choisi répertoire que je connais qui ne me pose aucun soucis. L'image d'origine je la connais donc je peux la remplacer facilement.

DOH !


Actuellement je suis sur une expression du type :
Code:
$code_html_2 = preg_replace('`src="(.*)"`', 'src="../../images_newsletter/newsletter_$numero_newsletter/$nom_image"', $code_html);
 
Nouveau WRInaute
J'ai un exemple qui se rapproche très fortement de ce que je veux faire : http://www.expreg.com/pregreplace.php

Code:
$chaineA="Test d'une url placée entre < et > <https://www.europeancards.com> balises ouvrante et fermantes";

//--- première version ---//
$chaine=preg_replace('`<([^>]+)>`', '<a href="$1" target="_blank">$1</a>', $chaineA);
echo $chaine;

Ici on récupère le contenu entre chevrons pour le remplacer par autre chose, si ce n'est qu'en plus on garde en mémoire grâce aux parenthèses me semble-t-il, le contenu entre chevrons pour le restructurer à la manière d'un lien cliquable.

Moi je veux la même chose si ce n'est que je veux récupérer ce qu'il y a dans
img="JE VEUX TROUVER CA ET LE REMPLACER QUELQUE SOIT LE CONTENU JE ME FICHE DE SAVOIR CE QUI EST ECRIT ICI"
pour le remplacer par
img="repertoire/image.jpg".

Ça semble si simple et pourtant ça ne marche pas...
 
Nouveau WRInaute
Je pense que je m'approche mais ce n'est toujours pas ça :
Code:
$code_html_2 = preg_replace('`(<img src=")([^"]+)(")`', '\\1'.$mon_arborescence.'\\2', $code_html);
 
WRInaute passionné
Et bien on va peut être pouvoir avancer.

img="JE VEUX TROUVER CA ET LE REMPLACER QUELQUE SOIT LE CONTENU JE ME FICHE DE SAVOIR CE QUI EST ECRIT ICI"

Toi tu t'en fous, mais pas PHP.
Pour chacune de tes images ça donnerait ça :
Code:
$newCode = preg_replace( array(
        '#src\\s*=\\s*"[^"]*'.preg_quote(htmlspecialchars($_FILES['image_1']['tmp_name']), '#' ).'"#',
        "#src\\s*=\\s*'[^']*".preg_quote(htmlspecialchars($_FILES['image_1']['tmp_name']), '#' )."'#"
        ), 'src="'.htmlspecialchars($repertoire_que_je_choisi.'/'.$nom_que_jai_choisi).'"',
        $codeActuel );
 
Nouveau WRInaute
J'ai l'impression qu'on se comprend enfin... et j'avoue que ça fait plaisir ^^

Bool a dit:
Pour chacune de tes images ça donnerait ça :
Code:
$newCode = preg_replace( array(
        '#src\\s*=\\s*"[^"]*'.preg_quote(htmlspecialchars($_FILES['image_1']['tmp_name']), '#' ).'"#',
        "#src\\s*=\\s*'[^']*".preg_quote(htmlspecialchars($_FILES['image_1']['tmp_name']), '#' )."'#"
        ), 'src="'.htmlspecialchars($repertoire_que_je_choisi.'/'.$nom_que_jai_choisi).'"',
        $codeActuel );

Je vais décortiquer pour qu'on voit ensemble ce que je ne comprend pas.

Code:
'#src\\s*=\\s*"[^"]*'.preg_quote(htmlspecialchars($_FILES['image_1']['tmp_name']), '#' ).'"#',

Expression commençant par src suivi de 0 à N espaces suivi de = suivi de 0 à N espaces suivi du double quote ouvrant suivi de n'importe quel caractère différent de double quote répété de 0 à N fois (je préfère de 1 à N) puis :
Code:
preg_quote(htmlspecialchars($_FILES['image_1']['tmp_name']), '#' )

Je ne comprends pas pourquoi il faut absolument traiter l'arborescence initiale. D'après ce que j'ai en tête il suffit de préciser qu'on remplace n'importe quelle suite de caractère par :
Code:
'src="'.htmlspecialchars($repertoire_que_je_choisi.'/'.$nom_que_jai_choisi).'"'

Et je crois que c'est là qu'on n'arrive pas à se mettre d'accord.


Ensuite fin de l'expression régulière on trouve la double quote fermante et on s'arrête là. Tout est ok. Il n'y a que le preg_quote... ci-dessus qui m'interpelle.

P.S. : Merci de pas avoir laissé tomber car on est bien seul sur ce coup-là mon vieux :p
 
WRInaute passionné
Je ne comprends pas pourquoi il faut absolument traiter l'arborescence initiale.

Le soucis c'est qu'il y a plusieurs tags images dans le fichier. Si on ne précise pas quelle image on cherche à remplacer, preg_replace va remplacer toutes les images d'un coup par la dernière valeur de "$nom_que_jai_choisi" ce qui n'est pas ce que tu souhaites je pense.

Pour reprendre ton premier exemple, avec ceci :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="file:///C|/Documents and Settings/Sebastien/Bureau/Dossier 1/nom_aleatoire_1.jpg" width="300" height="200" />
<img src="file:///C|/Documents and Settings/Sebastien/Bureau/Dossier 2/nom_aleatoire_2.gif" width="300" height="200" />
...</p></div>

on obtiendrait :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="./images_newsletter_1/image_2.jpg" width="300" height="200" />
<img src="./images_newsletter_1/image_2.jpg" width="300" height="200" />
...</p></div>

(c'est à dire image_2.jpg dans tous les tags <img> de la page)

De même, rien ne dit que la personne t'upload les images dans l'ordre des tags de la page, et si tu te retrouves à les inverser le résultat ne va pas être brillant non plus :
Code:
<div style="display:block; width:600px; margin:25px auto;"><p>
<img src="./images_newsletter_1/image_2.jpg" width="300" height="200" />
<img src="./images_newsletter_1/image_1.jpg" width="300" height="200" />
...</p></div>

Le "preg_quote" contenant le nom d'origine (juste le nom, pas l'arborescence) permet donc d'identifier quel tag <img> est concerné par le remplacement. :roll:
 
Nouveau WRInaute
Rah effectivement j'avais oublié de préciser que je faisais ensuite un split sur ma nouvelle arborescence puis un str_replace pour renommer les images correctement. Sur ce coup-là je me suis compliqué la vie et ta méthode est plus rapide et moins gourmande en ressource.

Je gratte de ce côté-là et j'espère que mon projet post sera un post de cloture ^^

Encore merci !
 
Nouveau WRInaute
DOH !

Je crois que PHP ne me veut pas aujourd'hui :cry:

Pensant être vraiment prêt du but j'étais tout excité afin de pouvoir enfin débloquer ce bout de script et bien non. Il y a quelque chose qui ne passe pas. Pour trouver quoi j'ai voulu réduire cette expression en une expression plus simple :

Code:
$newCode = preg_replace('#"([^"]+)"#', '"'.$mon_arborescence.'"', $codeActuel );

Le résultat est comme tu peux t'y attendre le remplacement de tout ce qui est contenu entre double quote par une arborescence similaire dans tous les champs. J'essaie ensuite de pousser un peu plus loin l'expression pour qu'elle fasse ce qu'on lui demande :
Code:
$newCode = preg_replace('#"([^"]+)'.preg_quote(htmlspecialchars($_FILES['image_1']['name'])).'"#', '"'.$mon_arborescence.'"', $codeActuel );

Et paf (le chien) ça ne marche plus ?!? Aucun champ n'est affecté le code n'est pas modifié.
On peut se dire tient que le résultat de preg_quote(htmlspecialchars($_FILES['image_1']['name'])) peut générer une erreur de part la modification de tel ou tel caractère alors on tente autrement on se dit maintenant on va essayer de modifier uniquement les src :
Code:
$newCode = preg_replace('`src="([^"]+)"`', '"'.$mon_arborescence.'"', $codeActuel );

J'ai enlevé la possibilité d'espace entre les caractères en veillant bien à ce que le code HTML n'en contienne pas. Le résultat est le même qu'au dessus, aucun champ n'est affecté.

MAYDAY MAYDAY...
 
WRInaute passionné
re,

un var_dump( $_FILES['image_1']['name'] ) donne quoi ?

si je récapitule :

avec celle ci, tout est remplacé :
Code:
$newCode = preg_replace('#"([^"]+)"#', 'XXX', $codeActuel );

avec celle ci, rien est remplacé :
Code:
$newCode = preg_replace('#src="([^"]+)"#', 'XXX', $codeActuel );

Si c'est le cas, refais voir le contenu de "$codeActuel" stp.
Vu les caractères en question il ne devrait pourtant pas y avoir de soucis coté charset :S
 
Nouveau WRInaute
Bool a dit:
re,

un var_dump( $_FILES['image_1']['name'] ) donne quoi ?

:arrow: string(12) "NEWS-1_1.jpg"


Bool a dit:
si je récapitule :

avec celle ci, tout est remplacé :
Code:
$newCode = preg_replace('#"([^"]+)"#', 'XXX', $codeActuel );

avec celle ci, rien est remplacé :
Code:
$newCode = preg_replace('#src="([^"]+)"#', 'XXX', $codeActuel );

Tout à fait dès que l'on rajoute du texte devant ou derrière les doubles quotes l'expression ne marche plus.

Bool a dit:
Si c'est le cas, refais voir le contenu de "$codeActuel" stp.
Vu les caractères en question il ne devrait pourtant pas y avoir de soucis coté charset :S

Effectivement pas de caractère problématique :?

Code:
<div style="display:block; width:600px; margin:25px auto;">
  <p>
<img src="file:///C|/Documents and Settings/Sebastien/Bureau/Newsletter test/NEWS-1_1.jpg" width="299" height="201" />
<img src="file:///C|/Documents and Settings/Sebastien/Bureau/Newsletter test/NEWS-1_2.gif" width="301" height="201" />
...
</p>
  </div>
 
WRInaute passionné
Et bien je sèche là. Je ne vois vraiment pas pourquoi ça ne fonctionnerait pas, et j'ai la flegme de tester moi même.
 
Nouveau WRInaute
Je creuse encore 24h et si cela ne marche pas il faudra que je repense intégralement la mécanique de mon application.

Pour ta gouverne au cas ou cela te donnerai une idée de génie ^^
=> Quand j'écris l'expression de la sorte :
Code:
$newCode = preg_replace('`[src="][^"]+"`', '"'.$mon_arborescence.'"', $codeActuel );

Il insère le code dès qu'il rencontre un s un r un c un = ou un " ce qui est normal. Ce qui l'est moins c'est qu'on dirait qu'il n'aime pas qu'on écrive src= directement dans l'expression, comme si il fallait le placer entre parenthèses (je dis des bêtises c'est juste un exemple les parenthèses ayant un autre sens dans ce cas).

J'ai essayé des combinaisons du style {1}[r]{1}[c]{1}[=]{1} pour essayer de contourner cela mais rien n'y fait.

To be continued...
 
Nouveau WRInaute
Eurêka :p

Faire autre chose et revenir plus tard sur un script ça a du bon parfois ^^
Je viens de trouver le bug même s'il n'en est pas un en 5 petites minutes, son nom : magic_quotes_gpc :)

Et oui par défaut il est à on sur le serveur et du coup il me remplace src= par src\= une fois le formulaire validé. Un simple petit stripslashes sur les données récupérées par POST et le tour est joué.

Encore merci Bool pour ton aide et vive les expressions régulières car c'est quand même vraiment puissant ;)
 
Discussions similaires
Haut