Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Extraire un mot-clef d'une chaine avec espaces

14 réponses
Avatar
Olivier Miakinen
Bonjour,

Dans une chaîne de caractères composée de 0, 1 ou plusieurs mots-clés
séparés par des espaces, je cherche le moyen le plus efficace pour
supprimer l'un des mots-clés s'il existe.


Pour que ma demande soit claire, voici quelques exemples dans lesquels
le mot-clé à extraire est "mot".

1) "mot" -> ""
(le mot-clé était seul dans la chaîne, la chaîne devient vide)

2) "avant mot" -> "avant"
"mot apres" -> "apres"
"avant mot apres" -> "avant apres"
(cas où le mot-clé est au début, au milieu ou à la fin de la chaîne)

3) "un-mot mot-cle mot_mot_mot" -> "un-mot mot-cle mot_mot_mot"
("mot" n'existe pas en tant que tel)

Je précise qu'un mot-clé ne peut se trouver qu'une seule fois au maximum
dans une chaîne, et qu'il ne contient jamais d'espaces.


À vrai dire, en parcourant la doc de JavaScript, j'ai vu que je pourrais
faire un truc de ce genre là :
- tableau1 = chaine.split(" ");
- tableau2 = new Array();
- pour tous les éléments de tableau1, les ajouter dans tableau2 s'ils
sont différents du mot-clé
- chaine = tableau2.join(" ")
Mais ça ne me semble pas très efficace. Je n'ai trouvé aucune méthode
native pour rechercher un élément dans un tableau, ni pour supprimer un
élément au milieu d'un tableau.


Y a-t-il une autre méthode ? J'ai pensé aux RegExp aussi, mais je ne
sais pas comment traiter efficacement les différents cas.


Cordialement,
--
Olivier Miakinen

10 réponses

1 2
Avatar
Le Fou
Olivier Miakinen <om+ a écrit

Dans une chaîne de caractères composée de 0, 1 ou plusieurs mots-clés
séparés par des espaces, je cherche le moyen le plus efficace pour
supprimer l'un des mots-clés s'il existe.
(...)
Mais ça ne me semble pas très efficace. Je n'ai trouvé aucune méthode
native pour rechercher un élément dans un tableau, ni pour supprimer un
élément au milieu d'un tableau.


Puisque tu as la doc JavaScript, cherche du coté de la méthode "replace" (de
l'objet "string").
J'ai pas la doc sous la main et je ne sais plus exactement comment elle
fonctionne, un truc du genre :
chaine.replace(/motClef/, " ");

--
A'tchao

Le Fou
http://www.ffessm-cd84.com/
http://ehiller.club.fr/

Avatar
YD
Dans une chaîne de caractères composée de 0, 1 ou plusieurs mots-clés
séparés par des espaces, je cherche le moyen le plus efficace pour
supprimer l'un des mots-clés s'il existe.
[...]
À vrai dire, en parcourant la doc de JavaScript, j'ai vu que je pourrais
faire un truc de ce genre là :
- tableau1 = chaine.split(" ");
- tableau2 = new Array();
- pour tous les éléments de tableau1, les ajouter dans tableau2 s'ils
sont différents du mot-clé
- chaine = tableau2.join(" ")
Mais ça ne me semble pas très efficace. Je n'ai trouvé aucune méthode
native pour rechercher un élément dans un tableau, ni pour supprimer un
élément au milieu d'un tableau.


Un objet Array ayant n'importe quoi comme éléments, les fonctions de
recherche... Par contre tu as raté la méthode splice (versions 'récentes'
de javascript requises).

Y a-t-il une autre méthode ? J'ai pensé aux RegExp aussi, mais je ne
sais pas comment traiter efficacement les différents cas.


Si tu as envie de te casser la tête... Formaliser tes conditions en une
RegExp...

Un exemple avec split, splice, join :

function extirp(mot, chaine){
var tableau=chaine.split(" ");
for(var i=0;i<tableau.length;i++)
if(tableau[i]==mot)tableau.splice(i,1);
return tableau.join(" ");
}

--
Y.D.

Avatar
Olivier Miakinen

Puisque tu as la doc JavaScript, cherche du coté de la méthode "replace" (de
l'objet "string").


Merci, j'y pense en effet, mais je vais devoir me livrer à quelques
contorsions pour traiter les cas où le mot à rechercher est au début, au
milieu ou à la fin.

J'ai pas la doc sous la main et je ne sais plus exactement comment elle
fonctionne, un truc du genre :
chaine.replace(/motClef/, " ");


Ah non, ça ne peut pas marcher avec un remplacement aussi simple. Il
suffit de voir ce que ça donne sur mes exemples :

1) "mot" -> ""



Ok ici.

2) "avant mot" -> "avant"
"mot apres" -> "apres"
"avant mot apres" -> "avant apres"



Ta commande donnerait respectivement "avant ", " apres" et
"avant apres", avec donc une espace de trop à chaque fois.

3) "un-mot mot-cle mot_mot_mot" -> "un-mot mot-cle mot_mot_mot"



Et là, ta commande donnerait "un- mot-cle mot_mot_mot", voire peut-être
"un- -cle ___" si je faisais un remplacement global. Inacceptable.

Désolé, mais je dois trouver autre chose. Je vais lire la réponse de YD.


Avatar
Olivier Miakinen

[...] ça ne me semble pas très efficace. Je n'ai trouvé aucune méthode
native pour rechercher un élément dans un tableau, ni pour supprimer un
élément au milieu d'un tableau.


Un objet Array ayant n'importe quoi comme éléments, les fonctions de
recherche...


Ça existe en PHP (array_search() et in_array()) alors qu'un tableau
peut tout aussi bien contenir n'importe quoi comme éléments. On peut
d'ailleurs se programmer soi-même la fonction de recherche (tu l'as
fait dans l'exemple ci-dessous), mais elle sera forcément moins efficace
qu'une fonction native implémentée en dur dans le navigateur.

Par contre tu as raté la méthode splice (versions 'récentes'
de javascript requises).


Non, je ne l'avais pas ratée, mais la doc trouvée sur selfhtml me
laissait entendre que ça ne fonctionnerait pas :

<cit. http://fr.selfhtml.org/javascript/objets/array.htm#splice>
En ne mentionnant que les deux premiers paramètres des *éléments*
*vides* seront insérés.
</cit.>

C'est vrai qu'une autre doc me donne plus d'espoir :
<http://www.devguru.com/Technologies/ecmascript/quickref/Splice.html>

Dans le premier cas, je me retrouverais avec une espace de trop, alors
que dans le second cas ce serait correct. Je vais essayer.

Y a-t-il une autre méthode ? J'ai pensé aux RegExp aussi, mais je ne
sais pas comment traiter efficacement les différents cas.


Si tu as envie de te casser la tête... Formaliser tes conditions en une
RegExp...


En fait, avec une RegExp, c'est faisable de la manière suivante :
- concaténer " " à la fin de la chaîne
- remplacer /bmot-clé / par ""
- supprimer un éventuel " " à la fin
Mais bon, c'est assez peu intuitif comme méthode.

Un exemple avec split, splice, join :

function extirp(mot, chaine){
var tableau=chaine.split(" ");
for(var i=0;i<tableau.length;i++)
if(tableau[i]==mot)tableau.splice(i,1);
return tableau.join(" ");
}


Je vais essayer, et je vous tiens au courant. Merci à toi !


Avatar
Olivier Miakinen
Le 03/09/2005 22:12, je répondais à YD :

Par contre tu as raté la méthode splice (versions 'récentes'
de javascript requises).


Non, je ne l'avais pas ratée, mais la doc trouvée sur selfhtml me
laissait entendre que ça ne fonctionnerait pas :

<cit. http://fr.selfhtml.org/javascript/objets/array.htm#splice>
En ne mentionnant que les deux premiers paramètres des *éléments*
*vides* seront insérés.
</cit.>


Bon, eh bien contrairement à ce que prétend fr.selfhtml.org, le second
paramètre de splice() est bien le nombre d'éléments à supprimer (non pas
le nombre à insérer) et il n'insère donc pas d'éléments vides. Bien fait
pour moi, j'apprendrai à me méfier de ce site.

Au passage, on dirait que c'était une erreur dans la version originale
en allemand (toujours servie aux anglophones car non traduite) alors que
la version courante en allemand a été corrigée.

Version allemande pour les anglophones :
http://en.selfhtml.org/javascript/objekte/array.htm#splice

Version allemande pour les germanophones :
http://de.selfhtml.org/javascript/objekte/array.htm#splice

Je vais essayer, et je vous tiens au courant. Merci à toi !


Ça marche finement. Encore merci !


Avatar
ASM
Olivier Miakinen wrote:
Bonjour,

Dans une chaîne de caractères composée de 0, 1 ou plusieurs mots-clés
séparés par des espaces, je cherche le moyen le plus efficace pour
supprimer l'un des mots-clés s'il existe.


Pour que ma demande soit claire, voici quelques exemples dans lesquels
le mot-clé à extraire est "mot".

1) "mot" -> ""
(le mot-clé était seul dans la chaîne, la chaîne devient vide)

2) "avant mot" -> "avant"
"mot apres" -> "apres"
"avant mot apres" -> "avant apres"
(cas où le mot-clé est au début, au milieu ou à la fin de la chaîne)

3) "un-mot mot-cle mot_mot_mot" -> "un-mot mot-cle mot_mot_mot"
("mot" n'existe pas en tant que tel)

Je précise qu'un mot-clé ne peut se trouver qu'une seule fois au maximum
dans une chaîne, et qu'il ne contient jamais d'espaces.


l'idée de l'array n'est pas si mauvaise

function enleverParArray(machaine,mot)
nouvtableau = new Array(), j=0;
tableau = machaine.split(' ');
for(var i=0;i<tableau.length;i++)
if(tableau[i]==mot) { nouvtableau[j]= tableau[i]; j++}
return nouvtableau.join(' ');
}

et :
machaine = machaine.replace(' mot ',' ');
çà ne te va pas ?

ha ! non trop simple !
alors comme tu veux tu choises :

function enlever(machaine,mot) {
if(machaine==mot) machaine = '';
else
if(machaine.indexOf(' '+mot+' ')>=0)
machaine = machaine.replace(' '+mot+' ',' ');
else
if(machaine.indexOf(mot+' ')==0)
machaine = machaine.replace(mot+' ','');
else
if(machaine.lastIndexOf(' '+mot)==(machaine.length-mot.length-1))
machaine = machaine.replace(' '+mot,'');
alert('['+machaine+']');
}

function enlever2(machaine,mot) {
machaine = machaine==mot?
'':
machaine.indexOf(' '+mot+' ')>=0?
machaine.replace(' '+mot+' ',' ') :
machaine.indexOf(mot+' ')==0?
machaine.replace(mot+' ','') :
machaine.lastIndexOf(' '+mot)==machaine.length-mot.length-1?
machaine = machaine.replace(' '+mot,'') :
machaine;
alert('['+machaine+']');
}


--
Stephane Moriaux et son [moins] vieux Mac

Avatar
Olivier Miakinen

et :
machaine = machaine.replace(' mot ',' ');
çà ne te va pas ?

ha ! non trop simple !


Alors plutôt :
machaine = (' '+machaine+' ').replace(' mot ',' ').trim(' ');
(en espérant que la méthode trim() existe, je n'ai pas vérifié)

alors comme tu veux tu choises :

[ des algos bien compliqués, comme j'aurais pu choisir si je ne
pensais pas à une éventuelle maintenance ]


Finalement, je me suis inspiré de l'idée de YD, et j'ai défini trois
nouvelles méthodes dans l'objet Array et deux nouvelles méthodes dans
l'objet Node. Ah oui, parce que je ne vous avais pas dit, mais le but de
l'opération est de pouvoir ajouter et retirer facilement des noms de
classes à des éléments du DOM.

Note, ASM, que ceci va me servir pour répondre à tes objections du mois
dernier à propos de ma page de charsets. Ce n'est pas encore en ligne
mais ça avance, ça avance...

-------------------------------------------------------------------

Array.prototype.arraySearch = function(needle)
{
for (var idx = 0; idx < this.length; idx++) {
if (this[idx] === needle) return idx;
}
return false;
}
Array.prototype.addElementIfMissing = function(element)
{
if (this.arraySearch(element) === false) {
this.push(element);
return true;
}
return false;
}
Array.prototype.removeElementIfPresent = function(element)
{
var idx = this.arraySearch(element);

if (idx !== false) {
this.splice(idx, 1);
return true;
}
return false;
}

-------------------------------------------------------------------

Node.prototype.addClassName = function(classe)
{
var classArray = this.className.split(" ");

if (classArray.addElementIfMissing(classe)) {
this.className = classArray.join(" ");
return true;
}
return false;
}
Node.prototype.removeClassName = function(classe)
{
var classArray = this.className.split(" ");

if (classArray.removeElementIfPresent(classe)) {
this.className = classArray.join(" ");
return true;
}
return false;
}

-------------------------------------------------------------------

Avatar
YD
Node.prototype.addClassName = function(classe)...

Node.prototype.removeClassName = function(classe)...


Attention, si ton objectif est une audience qui ne soit pas
restreinte à Fx et Opera (peut-être Konqueror ?)... IE ne
connaît pas l'objet Node et n'accepte pas l'ajout de méthodes
au prototype des objets du DOM, même si on ajoute la méthode à
l'objet Object, ce qu'acceptent les navigateurs cités plus haut
sans rechigner et transfèrent bien aux objets du DOM.

C'est très contrariant, n'est-ce pas ! Pas moyen de faire du
propre.

--
Y.D.

Avatar
Olivier Miakinen
Node.prototype.addClassName = function(classe)...

Node.prototype.removeClassName = function(classe)...


Attention, si ton objectif est une audience qui ne soit pas
restreinte à Fx et Opera (peut-être Konqueror ?)... IE ne
connaît pas l'objet Node


Je m'en suis rendu compte hélas, juste avant d'aller me coucher. J'étais
trop désespéré pour venir en parler tout de suite ici.

et n'accepte pas l'ajout de méthodes
au prototype des objets du DOM, même si on ajoute la méthode à
l'objet Object, ce qu'acceptent les navigateurs cités plus haut
sans rechigner et transfèrent bien aux objets du DOM.

C'est très contrariant, n'est-ce pas ! Pas moyen de faire du
propre.


Tant pis, je me contenterai de fonctions prenant un objet du DOM en
paramètre. Mais en effet, c'est très contrariant.

Est-ce qu'au moins je peux conserver mes définitions de méthodes pour
l'objet Array ?


Avatar
YD

Est-ce qu'au moins je peux conserver mes définitions de méthodes pour
l'objet Array ?


Oui, l'ajout au prototype des objets natifs ou définis par script de
javascript fait partie de la spécification. Le comportement des objets
de l'application hôte, par contre...

--
Y.D.

1 2