11548 sujets

JavaScript, DOM et API Web HTML5

Modérateur
Bonjour,

Je souhaite pouvoir récupérer dans une sélection de plusieurs images (sous forme de code html) chaque code d'image. Voici un exemple de sélection :
<img src="data/images/slider/1.jpg" alt="" /><img src="data/images/slider/2.jpg" alt="" /><img src="data/images/slider/3.jpg" alt="" /><img src="data/images/slider/4.jpg" alt="" /><img src="data/images/slider/5.jpg" alt="" /><img src="data/images/slider/6.jpg" alt="" />

Voici ce que je fais pour l'instant (currentSelection est le code sélectionné que j'ai collé ci-dessus) :

var imgPattern = /<img\s.*src=".*\.(?:gif|png|jpeg|jpg)".*>$/gi;
var imgInSelection = currentSelection.match(imgPattern);

Le problème est que ce qui est capturé est le code de toutes les images et non le code de chaque image (au lieu d'obtenir dans le tableau imgInSelection 6 éléments, je n'en obtiens qu'un, qui correspond au code que j'ai collé en premier).

Il me faut donc une autre regexp. J'ai tenté un peu tout et n'importe quoi, rien n'y fait, je n'arrive pas à trouver...

Un petit coup de pouce ? Smiley smile
Modifié par jojaba (23 Dec 2010 - 16:24)
Administrateur
Bonjour,

je suis une ouiche en Javascript mais il doit bien y avoir l'équivalent d'explode() (PHP) en JS ? Tu découpes entre chaque ">" et "<" et tu auras ton tableau.
Salut,

var imgInSelection = currentSelection.match(/<img\s.*?src=".+?\.(?:gif|png|jpe?g)"[^>]*>/ig);
for (var i = 0; i < imgInSelection.length; i++) {
	// imgInSelection[i] = code capturé #i
}


?[/i]
Modifié par Eric2A (23 Dec 2010 - 19:02)
Modérateur
Felipe a écrit :

je suis une ouiche en Javascript mais il doit bien y avoir l'équivalent d'explode() (PHP) en JS ?

Il semblerait que non. En tout cas, j'ai pas trouvé ça dans "Débuter en Javascript" aux éditions Eyrolles (c'est mon cadeau de Noël à moi-même Smiley langue )
Eric2A a écrit :
Salut,
var imgInSelection = currentSelection.match(/&lt;img\s.*?src=&quot;.+?\.(?:gif|png|jpe?g)&quot;[^&gt;]*&gt;/ig);
for (var i = 0; i &lt; imgInSelection.length; i++) {
	// imgInSelection[i] = code capturé #i
}


?[/i]

Tha's it ! Merci Eric.
Je savais que le problème venait de ".*" qui correspond à "n'importe quel caractère",il fallait être plus restrictif, mais je ne savais pas vraiment comment faire... Ceci dit, j'aurais aimé comprendre la signification de ".+?" qui est ici la clé de résolution. Pour "[^&gt;]*" c'est une assertion c'est ça ? Pas compris pourquoi on met le "*" pour cette assertion... Merci pour tes éventuelles explications.
J'explique rapidement ce que je veux faire en réalité afin de vous soumettre une autre regexp pour validation de votre part...
En fait, je veux récupérer tous les attributs "src" du code des images sélectionnées dans un textarea pour les réutiliser dans dewslider. Mais je me suis rendu compte qu'on pouvait aussi trouver des sources d'images dans les balises lien (<a>), donc je vais plutôt faire un recherche sur l'adresse d'images contenues dans la sélection. Mon motif devient (suite à la proposition d'Eric) ceci :
var ImgSrcPattern = /(http:|data).+?\.(?:gif|png|jpe?g)[^"]*/ig;

Le chemin peut donc être un chemin absolu vers le fichier image (commence par "http") ou relatif (dans ce cas, il commence par "data", c'est le nom du dossier dans lequel se trouvent les images dans le cms que j'utilise). Vous pouvez confirmer que c'est correct (en tout cas ça marche pour moi) ?
Ça me simplifie la tâche d'ailleurs puisque la liste des sources est donnée séparée par des virgules (ce dont j'ai besoin pour placer ça dans le code du slideshow), je n'ai pas besoin de faire de boucle "for" pour le listage ! Smiley smile
Au cas où je ne reviendrais pas ici avant demain, je tiens à souhaiter à toute l'équipe d'Alsacréation et aux habitués du site un Joyeux Noël Smiley biggrin
a écrit :
j'aurais aimé comprendre la signification de ".+?"


.+?\.

. (meta-caractère) = n'importe quel caractère
+ (quantificateur) = apparaissant une ou plusieurs fois

? Permet d'inverser la tendance à la gourmandise. Ainsi, le moteur d'expression rationnelles saura s'arrêter au premier élément trouvé - le point (\.) avant l'extension en l'occurence -.

a écrit :
"[^>]*" c'est une assertion c'est ça ? Pas compris pourquoi on met le "*"


Il s'agit d'une classe négative.

[^>] N'importe quel caractère hormis >
* (quantificateur) = qu'il y en ai un, plusieurs ou pas du tout.

Pour la suite, tu souhaites capturer l'adresse de la balise a ou de la balise img ?
Modérateur
a écrit :
? Permet d'inverser la tendance à la gourmandise. Ainsi, le moteur d'expression rationnelles saura s'arrêter au premier élément trouvé - le point (\.) avant l'extension en l'occurence -.

C'est ça que j'avais pas compris. Ce côté "gourmand" je voulais l'empêcher et tu me donnes-là exactement ce que je recherchais, merci.
a écrit :
Pour la suite, tu souhaites capturer l'adresse de la balise a ou de la balise img ?

Peu importe. Ce que je souhiates capturer dans la sélection, c'est tout chemin vers une image (que ce chemin se trouve dans une balise image ou une balise lien). Je pense que ce que j'ai trouvé avec ton aide doit être bon Smiley cligne

Merci encore pour ce gros coup de pouce !
Modérateur
Une dernière petite question. Si je n'ai pas de balises img ou lien dans la sélection et que je veux récupérer juste tout ce qui peut représenter une source d'images (dans ce cas, il n'y aurait pas de « " » pour faire "arrêter" la capture). Quel pourrait être le motif ?
D'autre part, je voudrai pouvoir insérer une variable dans le motif de recherche, est-ce possible ?
Je voudrais pouvoir remplacer "data" dans l'expression suivante par une variable nommée "images_folder" :
var ImgSrcPattern = /(http|data).+?\.(?:gif|png|jpe?g)[^"]*/ig;

Modifié par jojaba (26 Dec 2010 - 11:20)
Re,

jojaba a écrit :
je veux récupérer juste tout ce qui peut représenter une source d'images.

Nous plaçons l'assertion simple \b au début et à la fin du motif recherché (l'URL absolue ou relative vers une image en l'occurence).

jojaba a écrit :
insérer une variable dans le motif de recherche, est-ce possible ?

Oui,
Pour créer/modifier dynamiquement des expressions régulières, nous définissons une instance de l'objet RegExp.


var str='Img#1=http://localhost/img/1.jpg ; Img#2=data/images/slider/2.jpg';

var images_folder='data/images/slider/';

var pattern='\\b(?:http://|'+images_folder+').+?\.(?:gif|png|jpe?g)\\b'; // Création du motif
var re = new RegExp(pattern,'ig');

var imgInSelection = str.match(re);
if(imgInSelection !=null){
	for (var i = 0; i < imgInSelection.length; i++) {
		alert(imgInSelection[i]);
	}
}
[/i]
Modérateur
Ok Eric, vraiment sympa de t'occuper de moi ainsi !
J'ai testé ta proposition. ça fonctionne sauf pour le cas où les deux adresses des images ne sont pas séparées :
data/images/slider/5.jpgdata/images/slider/6.jpg

Il faudrait que la capture s'arrête après l'extension. Un peu fatigué là donc je ne vais pas tester ce que je propose...
var pattern='\\b(?:http://|'+images_folder+').+?\.(?:gif|png|jpe?g)?\\b';

???

a+
jojaba a écrit :
ça fonctionne sauf pour le cas où les deux adresses des images ne sont pas séparées

Il faut qu'elles soient séparées.

Le motif...
/*
\b(?:http://|'+images_folder+').+?\.(?:gif|png|jpe?g)\b
*/

va "voir" la chaine...
/*
data/images/slider/5.jpgdata/images/slider/6.jpg
*/

comme ceci :
/*
(?:http://|data/images/slider/)	=>	data/images/slider/
.+?								=>	5.jpgdata/images/slider/6
\.(?:gif|png|jpe?g)				=>	.jpg
*/

Car elle cherche une chaine de caractères se terminant par une extension.

Je vois pas comment faire sinon.


Concernant ton dernier motif...
/*
(?:gif|png|jpe?g)?
*/

Le point d'intérogation final a pour effet de rendre l'extension facultative alors qu'elle doit être obligatoire.
Modifié par Eric2A (27 Dec 2010 - 22:10)
Modérateur
Merci encore pour ces explications qui m'aident vraiment (même si pour l'instant, je pédale encore un peu dans la choucroute Smiley ravi ).
Tu dis ceci :

/* 
(?:http://|data/images/slider/)    =>    data/images/slider/ 
.+?                                =>    5.jpgdata/images/slider/6 
\.(?:gif|png|jpe?g)                =>    .jpg 
*/ 


Et si on lui demandait de "refuser" les "." ou même l'expression du type "\.(?:\.(?:gif|png|jpe?g)" deux fois (l'empêcher d'être gourmand) dans la deuxième partie que tu as indiquée ci-dessus ? Tu m'as dit que le "?" permettait de rendre le ".*" moins gourmand (c'est d'ailleurs pour ça que j'avais ajouté le "?" dans l'expression que je proposais et qui ne fonctionne pas, je le confirme). Ne pourrrait-on pas essayer quelque chose comme ça ?
Je vais voir ça dès que possible et reviens ici pour un rapport détaillé Smiley cligne
Je vais en tout cas commencer par enlever les "\b" et utiliser le fait que l'expression commence par "http://" ou "data/images" et se termine par une extension d'un des 4 types et ne contient pas un point suivi d'un des 4 types. C'est le bon raisonnement ?
Modifié par jojaba (28 Dec 2010 - 14:42)
Re,

La signification du point d'interogation dépend de sa postion dans le motif.

1) Après un caractère (ou plusieurs entre parenthèses/crochets)

? est un quantificateur qui est l'équivalent de {0,1}.

Par exemple : jpe?g ( équivalent de jpe{0,1}g ) rend le caractère 'e' facultatif.


2) Après un quantificateur * ou +

? est un quantificateur de minimisation (l'inversion de la tendance à la gourmandise).


jojaba a écrit :
Je vais en tout cas commencer par enlever les "\b"...

Si on enlève l'ancrage (\b) ça fonctionne effectivement.

var pattern='(?:http://|'+images_folder+').+?\.(?:gif|png|jpe?g)';
var re = new RegExp(pattern,'ig');
Bonjour,

Juste une question, je ne voudrais pas vous disperser mais pourquoi avoir fait cela avec une expression régulière ?
N'aurait t'il pas été plus simple de récupérer les balises images et pour chacune d'entre elle récupérer l'attribut source (src) ?

Faire du javascript quoi Smiley smile
Modérateur
KalNex a écrit :
Bonjour,

...pourquoi avoir fait cela avec une expression régulière ?
N'aurait t'il pas été plus simple de récupérer les balises images et pour chacune d'entre elle récupérer l'attribut source (src) ?
Faire du javascript quoi Smiley smile

Bonjour,
C'est ce que je voulais faire d'abord : http://forum.alsacreations.com/topic-5-52873-1-Recuperation-src-dimages-dans-une-selection.html
Mais comme je veux récupérer la source des images dont le code est dans un textarea (dans le cadre d'un éditeur de texte pour cms, pluxml en l'occurrence), je ne peux pas le faire comme je le ferais dans une page Web Smiley cligne