Форматировать строку JavaScript, используя заполнители и объект подстановок? - PullRequest
63 голосов
/ 02 ноября 2011

У меня есть строка с выражением: My Name is %NAME% and my age is %AGE%.

%XXX% являются заполнителями.Нам нужно подставить туда значения из объекта.

Объект выглядит следующим образом: {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"}

Мне нужно проанализировать объект и заменить строку соответствующими значениями.Таким образом, окончательный результат будет:

Меня зовут Майк, и мне 26 лет.

Все это должно быть сделано либо с использованием чистого JavaScript, либо с помощью jquery.

Ответы [ 10 ]

102 голосов
/ 02 ноября 2011

Требования исходного вопроса явно не могут выиграть от интерполяции строк, так как кажется, что это обработка произвольных ключей замены во время выполнения.

Однако , если вам просто нужно было выполнить интерполяцию строк, вы можете использовать:

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

Обратите внимание на разделительные знаки, разделяющие строку, они обязательны.


Для ответа, отвечающего требованиям конкретного ОП, вы можете использовать String.prototype.replace() для замены.

Следующий код будет обрабатывать все совпадения и не затрагивать их без замены (если ваши значения замены - это все строки, если нет, см. Ниже).

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 .

Если некоторые из ваших замен не являются строками, сначала убедитесь, что они существуют в объекте. Если у вас есть формат, подобный примеру, то есть, заключенный в знаки процента, вы можете использовать оператор in для достижения этой цели.

jsFiddle .

Однако, если ваш формат не имеет специального формата, т. Е. Какой-либо строки, а ваш объект-заменитель не имеет прототипа null, используйте Object.prototype.hasOwnProperty(), если только вы не можете гарантировать, что ни одна из ваших потенциальных замененных подстрок не будет будет конфликтовать с именами свойств в прототипе.

jsFiddle .

В противном случае, если ваша замещающая строка будет 'hasOwnProperty', вы получите результирующую испорченную строку.

jsFiddle .


В качестве дополнительного примечания вас должны называть replacements Object, а не Array.

23 голосов
/ 25 декабря 2016

Как насчет использования литералов шаблонов ES6?

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

Подробнее о литералах шаблонов ...

11 голосов
/ 04 сентября 2015

Вы можете использовать JQuery (jquery.validate.js), чтобы сделать это легко.

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

Или, если вы хотите использовать только эту функцию, вы можете определить эту функцию и просто использовать ее как

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"]));

кредит команде jquery.validate.js

7 голосов
/ 04 февраля 2017

Как и в современном браузере, заполнитель поддерживается новой версией Chrome / Firefox, аналогично функции стиля C printf().

Заполнители:

  • %s Строка.
  • %d, %i Целое число.
  • %f Число с плавающей запятой.
  • %o Гиперссылка объекта.

например

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

КСТАТИ, , чтобы увидеть результат:

  • В Chrome используйте ярлыкCtrl + Shift + J или F12, чтобы открыть инструмент разработчика.
  • В Firefox используйте ярлык Ctrl + Shift + K, чтобы открыть инструмент разработчика. (Не используйте F12, который откроет Firebug, который больше не поддерживается, и на его вкладке консоли не будет отображаться сообщение) .

@ Update - поддержка nodejs

Кажется, nodejs не поддерживает %f, вместо этого может использовать %d в nodejs.С %d число будет напечатано как плавающее число, а не просто целое число.

4 голосов
/ 02 ноября 2011

Просто используйте 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%"]);
3 голосов
/ 02 ноября 2011

Вы можете использовать пользовательскую функцию замены следующим образом:

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);

Вы можете увидеть, как она работает здесь: http://jsfiddle.net/jfriend00/DyCwk/.

2 голосов
/ 26 января 2019

Вот еще один способ сделать это путем динамического использования литералов шаблона es6 во время выполнения.

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
1 голос
/ 20 июля 2017

Это позволяет вам сделать именно это

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

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

Делая следующее:

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

// My username is tjcafferkey on Git
1 голос
/ 03 февраля 2016

Если вы хотите сделать что-то ближе к console.log, например, заменить% s заполнителей, как в

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

Я написал это

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"/>

вы получите

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

UPDATE

Я добавил простой вариант как String.prototype, полезный при работе со строковыми преобразованиями, вот он:

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;
   }

В этом случае вы будете делать

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

Попробуйте эту версию здесь

1 голос
/ 12 июля 2015

В качестве быстрого примера:

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

Выход:

Джек 40 лет

...