web-dev-qa-db-fra.com

Formater une chaîne JavaScript en utilisant des espaces réservés et un objet de substitution?

J'ai une chaîne avec say: My Name is %NAME% and my age is %AGE%.

%XXX% sont des espaces réservés. Nous devons y substituer des valeurs à partir d'un objet.

L'objet ressemble à: {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"}

Je dois analyser l'objet et remplacer la chaîne par les valeurs correspondantes. Donc, le résultat final sera:

Je m'appelle Mike et j'ai 26 ans.

Le tout doit être fait en utilisant du javascript pur ou jquery.

51
Joby Joseph

Les exigences de la question initiale ne pouvaient manifestement pas tirer parti de l'interpolation des chaînes, car il semble que ce soit un traitement d'exécution de clés de remplacement arbitraires. 

Cependant, si vous venez d'effectuer une interpolation de chaîne, vous pouvez utiliser:

const str = `My name is ${replacements.name} and my age is ${replacements.age}.`

Notez les backticks délimitant la chaîne, ils sont obligatoires.


Pour obtenir une réponse adaptée aux besoins de l'OP, vous pouvez utiliser String.prototype.replace() pour les remplacements.

Le code suivant gérera toutes les correspondances et ne touchera pas celles sans remplacement (tant que vos valeurs de remplacement sont toutes des chaînes, sinon, voir ci-dessous).

var replacements = {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"},
    str = 'My Name is %NAME% and my age is %AGE%.';

str = str.replace(/%\w+%/g, function(all) {
   return replacements[all] || all;
});

jsFiddle .

Si certains de vos remplacements ne sont pas des chaînes, assurez-vous qu'ils existent d'abord dans l'objet. Si vous avez un format comme celui-ci, c’est-à-dire entouré de signes de pourcentage, vous pouvez utiliser l’opérateur in pour y parvenir.

jsFiddle .

Toutefois, si votre format ne possède pas de format spécial, c’est-à-dire une chaîne, et que votre objet de remplacement n’a pas de prototype null, utilisez Object.prototype.hasOwnProperty(), à moins que vous ne puissiez garantir qu’aucune de vos sous-chaînes remplacées potentielles ne se trouvera en conflit avec les noms de propriété figurant sur la liste. prototype.

jsFiddle .

Sinon, si votre chaîne de remplacement était 'hasOwnProperty', vous obtiendrez une chaîne endommagée.

jsFiddle .


En remarque, vous devriez être appelé replacements une Object, pas une Array.

85
alex

Que diriez-vous d'utiliser des littéraux de modèle ES6? 

var a = "cat";
var b = "fat";
console.log(`my ${a} is ${b}`); //notice back-ticked string

Plus d'informations sur les modèles de littéraux ...

20
Tomasz Mularczyk

Vous pouvez utiliser JQuery (jquery.validate.js) pour que cela fonctionne facilement.

$.validator.format("My name is {0}, I'm {1} years old",["Bob","23"]);

Ou si vous voulez utiliser uniquement cette fonctionnalité, vous pouvez définir cette fonction et l'utiliser comme

function format(source, params) {
    $.each(params,function (i, n) {
        source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
    })
    return source;
}
alert(format("{0} is a {1}", ["Michael", "Guy"]));

crédit à l'équipe jquery.validate.js

10
zawhtut

Comme pour les navigateurs modernes, les espaces réservés sont pris en charge par la nouvelle version de Chrome/Firefox, similaire à la fonction de style C printf().

Placeholders:

  • %s Chaîne.
  • %d, %i Nombre entier.
  • %f Nombre à virgule flottante.
  • %o hyperlien d'objet.

par exemple.

console.log("generation 0:\t%f, %f, %f", a1a1, a1a2, a2a2);

BTW, pour voir la sortie:

  • Sous Chrome, utilisez le raccourci Ctrl + Shift + J ou F12 pour ouvrir l'outil de développement.
  • Dans Firefox, utilisez le raccourci Ctrl + Shift + K pour ouvrir l’outil de développement. (N'utilisez pas F12 qui ouvrira Firebug qui n'est plus maintenu, et son onglet de console ne affichera pas le message).

@Update - support nodejs

Il semblerait que nodejs ne supporte pas %f; à la place, vous pouvez utiliser %d dans nodejs . Avec %d, le nombre sera imprimé sous forme de nombre flottant, et pas uniquement d'entier.

7
Eric Wang

Vous pouvez utiliser une fonction de remplacement personnalisée comme ceci:

var str = "My Name is %NAME% and my age is %AGE%.";
var replaceData = {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"};

function substitute(str, data) {
    var output = str.replace(/%[^%]+%/g, function(match) {
        if (match in data) {
            return(data[match]);
        } else {
            return("");
        }
    });
    return(output);
}

var output = substitute(str, replaceData);

Vous pouvez le voir fonctionner ici: http://jsfiddle.net/jfriend00/DyCwk/ .

3
jfriend00

Il suffit d'utiliser replace()

var values = {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"};
var substitutedString = "My Name is %NAME% and my age is %AGE%.".replace("%NAME%", $values["%NAME%"]).replace("%AGE%", $values["%AGE%"]);
2
hafichuk

Cela vous permet de faire exactement cela 

NPM: https://www.npmjs.com/package/stringinject

GitHub: https://github.com/tjcafferkey/stringinject

En procédant comme suit:

var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });

// My username is tjcafferkey on Git
1
tjcafferkey

Si vous voulez faire quelque chose de plus proche de console.log, comme remplacer les espaces réservés de% s

>console.log("Hello %s how are you %s is everything %s?", "Loreto", "today", "allright")
>Hello Loreto how are you today is everything allright?

J'ai écrit ça

function log() {
  var args = Array.prototype.slice.call(arguments);
  var rep= args.slice(1, args.length);
  var i=0;
  var output = args[0].replace(/%s/g, function(match,idx) {
    var subst=rep.slice(i, ++i);
    return( subst );
  });
   return(output);
}
res=log("Hello %s how are you %s is everything %s?", "Loreto", "today", "allright");
document.getElementById("console").innerHTML=res;
<span id="console"/>

tu auras

>log("Hello %s how are you %s is everything %s?", "Loreto", "today", "allright")
>"Hello Loreto how are you today is everything allright?"

METTRE &AGRAVE; JOUR

J'ai ajouté une variante simple en tant que String.prototype utile pour traiter les transformations de chaînes, la voici:

String.prototype.log = function() {
    var args = Array.prototype.slice.call(arguments);
    var rep= args.slice(0, args.length);
    var i=0;
    var output = this.replace(/%s|%d|%f|%@/g, function(match,idx) {
      var subst=rep.slice(i, ++i);
      return( subst );
    });
    return output;
   }

Dans ce cas vous ferez

"Hello %s how are you %s is everything %s?".log("Loreto", "today", "allright")
"Hello Loreto how are you today is everything allright?"

Essayez cette version ici

1
loretoparisi

Voici une autre façon de procéder en utilisant dynamiquement les littéraux de modèle es6 lors de l'exécution.

const str = 'My name is ${name} and my age is ${age}.'
const obj = {name:'Simon', age:'33'}


const result = new Function('const {' + Object.keys(obj).join(',') + '} = this.obj;return `' + str + '`').call({obj})

document.body.innerHTML = result

0
Simon Schärer

Comme exemple rapide:

var name = 'jack';
var age = 40;
console.log('%s is %d yrs old',name,age);

La sortie est: 

jack a 40 ans

0
Yomi